2014년 10월 17일 금요일

웹 이미지 가져와서 android app에서 보여주기


앞에서 진행한 예제는 일반 java 어플용 GetHttp 라는 클래스를 만들었다.
해당 클래스를 이용하여 안드로이드 App에서 이미지를 표시하는 방법을 알아보자. 버튼을 누르면 이미지가 나오는 간단한 어플인데, 완성 모습은 아래와 같다.

xml에 버튼과 image view를 추가한다.
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Button" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="17dp"
        android:src="@drawable/ic_launcher" />

버튼을 누르면 서버에서 이미지를 가져와야 하므로 로딩 중 화면이 나오면 더 좋겠다.

구현은 버튼을 누르는 동작과 연결되기때문에 버튼의 onClickListener에 등록한다.
Button Button1 = (Button) findViewById(R.id.button1);

        Button1.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View arg0) {
         
    dialog = new ProgressDialog(context);
    dialog.setTitle("Wait...");
    dialog.setMessage("Please wait while loading...");
    dialog.setIndeterminate(true);
    dialog.setCancelable(false);
    dialog.show();
    
    Thread nthread = new Thread(new Runnable() {
     public void run() {
      ...여기에 Network 접속 처리하는 코드를 넣는다....
     }
    });
    
    nthread.start();
    
   }
        });


그리고 GetHttp 함수를 UI에서 직접호출하면 Exception이 발생하게 된다. 따라서 thread를 이용하도록 한다. 완료된 후에는 아래와 같은 모습이 된다.
해당내용의 thread 완성 내용은 아래와 같다.
네트워크를 통해서 데이터를 받아온뒤 progress dialog 를 닫아주고 sendMessage를 보내 이미지가 draw되도록 한다.
    Thread nthread = new Thread(new Runnable() {
     public void run() {
      try {
       GetHttp html = new GetHttp();
       boolean ret = html.execute("http://img.s-msn.com/tenant/amp/entityid/BB9oYEf.img?h=187&w=300&m=6&q=60&u=t&o=t&l=f&f=jpg");
       Utils.fileWriteByte(context.getCacheDir()+"/test.jpg",html.getByte());
       if( ret ) {
        dialog.dismiss();

        Message msg = mainHandler.obtainMessage();
        msg.what = MSG_DRAW_IMG;
        msg.obj = new String(context.getCacheDir()+"/test.jpg");
        mainHandler.sendMessage(msg);

       }else{
        dialog.dismiss();
       }
      } catch (Throwable ex) {
       ex.printStackTrace();
       dialog.dismiss();
      }
     }
    });

핸들러를 이용해서 이미지를 받아주는 부분이다.
이렇게 처리해주는 이유는 Thread 안에서 직접 UI draw 함수를 사용할 수 없기 때문이다.
class MainHandler extends Handler {
  @Override
  public void handleMessage(Message msg) {
   super.handleMessage(msg);
   switch (msg.what) {
   case MSG_DRAW_IMG:
    String file = (String) msg.obj;
    ImageView iv = (ImageView) findViewById(R.id.imageView1);

    // 참고소스:http://www.androidpub.com/2426245
    // Get the dimensions of the View
    int targetW = iv.getWidth();
    int targetH = iv.getHeight();

    // Get the dimensions of the bitmap
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(file, bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    // Determine how much to scale down the image
    int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

    // Decode the image file into a Bitmap sized to fill the View
    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;
    bmOptions.inPurgeable = true;

    Bitmap bitmap = BitmapFactory.decodeFile(file, bmOptions);
    iv.setImageBitmap(bitmap);

    break;
   default:
    break;
   }
  }

 };

전체 소스

댓글 없음:

댓글 쓰기