마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

웹에서 이미지를 받아오는 예제 문제

0 추천

인터넷에서 안드로이드 어플로 웹에 있는 이미지를 불러오는 예제를

돌려보는 도중 오류가 생겨 로그를 찾아보니 UI 부분과 네트워크 부분을 다른 스레드를

이용하여 작성해야 한다고 나오더군요 ㅠ 급한데 어떤식으로 해야 할지 알려주실수 있을까요?

package com.example.imageparse;   
  
import java.io.IOException;   
import java.io.InputStream;   
import java.net.HttpURLConnection;   
import java.net.MalformedURLException;   
import java.net.URL;   
import java.util.HashMap;   
import java.util.Map;   
import java.util.Random;   
import android.app.Activity;   
import android.os.Bundle;   
import android.graphics.Bitmap;   
import android.graphics.BitmapFactory;   
import android.util.Log;   
import android.view.View;   
import android.widget.Button;   
import android.widget.EditText;   
import android.widget.ImageView;   
public class WebImageParse extends Activity    
{   
    ImageView imView;   
    String imageUrl = "http://cfs.see.daum.net/files/admin/20090113/20090113_092517_best_dormitory_090113.jpg "; // 이미지를 파싱해올 URL   
    Random r; // 사진을 랜덤으로 불러오기위한 랜덤변수    
    /** Called when the activity is first created. */  
    @Override  
   public void onCreate(Bundle savedInstanceState)    
    {   
       super.onCreate(savedInstanceState);   
      setContentView(R.layout.main);   
        r = new Random(); // 랜덤을 초기화 합니다.    
       Button bt3 = (Button)findViewById(R.id.get_imagebt); // 버튼을 연결시켜줍니다.   
       bt3.setOnClickListener(getImgListener); // 버튼에  클릭이벤트를 감지할 리스너를 설치해줍니다.   
        imView = (ImageView)findViewById(R.id.imview); // 이미지를 읽어들일 이미지뷰를 연결해줍니다.   
           
    }   
       
   // 클릭이벤트가 발생했을경우 의 처리를 해주는 함수입니다.   
    View.OnClickListener getImgListener = new View.OnClickListener()    
    {   
        
       @Override  
        public void onClick(View v) // 클릭이 일어났을경우     
        {   
           // TODO Auto-generated method stub   
            int i = r.nextInt()%4+1; // i 에 랜덤한 숫자를 생성시켜줍니다.    
            downloadFile(imageUrl+i+".png"); // 해당파일을 다운로드 합니다.    
           Log.i("im url",imageUrl+i+".png"); // 디버깅을 위한 Log를 설정해줍니다.    
        }   
    };   
    Bitmap bmImg; // 비트맵을처리할 변수를 생성합니다.   
     // 이미지를 다운로드하는 함수입니다. 파라미터는 String형   
    // fileUrl 이 들어갑니다.    
    void downloadFile(String fileUrl)    
    {   
        URL myFileUrl = null; // URL 타입의 myFileUrl을  NULL로 초기화 시켜줍니다.    
           
        try  
        {   
            myFileUrl = new URL(fileUrl); //  파라미터로 넘어온 Url을 myFileUrl에 대입합니다.   
              
        }   
        catch(MalformedURLException e) // 예외처리를 해줍니다.   
        {   
            // Todo Auto-generated catch block   
            e.printStackTrace();   
        }   
        try  
        {   
            // 실질적인 통신이 이루어지는 부분입니다.   
            // myFileUrl 로 접속을 시도합니다.    
            HttpURLConnection conn = (HttpURLConnection)myFileUrl.openConnection();   
            conn.setDoInput(true);   
            conn.connect();   
            int length = conn.getContentLength(); // 받아온 컨텐츠의 길이를 length 변수에 저장합니다.   
            InputStream is = conn.getInputStream(); // InputStream is 변수에 받아온 InputStream을 저장합니다.   
               
            bmImg = BitmapFactory.decodeStream(is); // 받아온 이미지를 bmImg에 넣어둡니다.   
            imView.setImageBitmap(bmImg); // imView에 이미지를 셋팅합니다.   
        }   
        catch(IOException e) // 예외처리를 해줍니다.   
        {   
            e.printStackTrace();    
        }   
    }   
}  

 

lonely0826 (140 포인트) 님이 2013년 5월 30일 질문

2개의 답변

0 추천
이 답변이 질문자님이 원하는건지는 잘 모르겟는데

ui 스레드를 다른 스레드가 건들어서 그런거같습니다.

비슷한 문제를 핸들러로 해결한거같은데

제가한소스 올립니다..

 

mHandler.sendEmptyMessage(0); //이것을 핸들러를 작동시킬 곳에 넣으세요

 

  //안드로이드에서는 백그라운드 스레드가 UI스레드에 접근하는 것을 허용하지 않는다.. 그래서 핸들러르 사용해야한다.
  private final Handler mHandler = new Handler() { //핸들러를 통해 UI스레드에 접근한다.

         @Override
         public void handleMessage(Message msg) {
             super.handleMessage(msg);

//이 아래부터는 자기가 하고싶은 ui 건드리는 작업.
             MainWindow.nodestartbt.setText("start");
             MainWindow.previewbt.setText("preview");
         }
        
     };
익명사용자 님이 2013년 5월 30일 답변
0 추천

버튼을 누를때 downloadFile 메서드가 호출되면서 그안에 있는 네트워크 동작들이 수행될때 문제가 발생했는가보네요

외부 쓰레드를 생성해서 downloadFile 를 호출하면 되는데 그렇게되면 외부쓰레드에서 

imView.setImageBitmap(bmImg);부분 수행할때 다시 앱이 죽어버리는 증상이 나타날꺼에요

외부 쓰레드에서도 메인 ui 를 건들면 안되거든요..

http://developer.android.com/reference/android/os/AsyncTask.html

AsyncTask 를 사용하시거나 핸들러를 이용해 해결해보세요..  핸들러 이용 예제는 먼저번 댓글 남기신분이 자세히 알려주셨네요

블랙넥원 (9,600 포인트) 님이 2013년 5월 30일 답변
...