메뉴 건너뛰기

조회 수 9842 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부







안드로이드에서 이미지를 보여주는 방법은 여러 가지가 있습니다. 가장 기본적인 방법은 어플내에 있는 그림파일을 보여주는 것인데, 어플에서 여러 그림을 사용하는 경우 어플의 용량이 증가하는 단점이 있고, 동적으로 그림을 바꿔주지 못한다는 단점이 있습니다. 동적으로 그림을 바꿔주지 못한다는 것은 새로운 그림으로 교체하고 싶을 때는 어플을 업데이트해야지만 그림을 교체할 수 있다는 것입니다.




이런 문제점들을 해결하는 방법은 서버에서 이미지를 받아오는 방법입니다. 서버에서 그림을 받아오기 때문에 어플용량에 대한 부담을 덜어주고, 이미지를 바꾸고 싶은 경우에는 서버에서 이미지만 교체하면 됩니다. 




단순히 서버에서 이미지를 받아오는 것은 다음과 같습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    public void loadBitmap(String strUrl) {
 
        Bitmap bitmap = null;
 
        try { 
 
            URL url = new URL(strUrl);
 
            HttpURLConnection conn =  (HttpURLConnection)url.openConnection(); 
 
            conn.setDoInput(true); 
 
            conn.connect(); 
 
            
 
            InputStream is = conn.getInputStream(); 
 
            bitmap = BitmapFactory.decodeStream(is); 
 
            imView.setImageBitmap(bmp); 
 
        } catch (IOException e) 
 
        { 
 
                e.printStackTrace(); 
 
        } 
 
    }




그림파일에 대한 URL을 받아와서 HttpURLConnection 을 이용해 연결한후, 그림을 스트림으로 받아와서 비트맵파일로 만들어 마지막에 imView.setImageBitmap 을 사용해 뷰에 그림을 띄웁니다.


하지만 이 코드를 사용해서 프로그램을 실행시키면 다음과 같은 오류가 발생합니다.





이는 허니콤버전 이후 안드로이드에서 네트워크 작업을 할 때 메인스레드에서 실행 시 발생하는 오류입니다. 네트워크 작업은 별도의 스레드에서 하는 것이 안정적입니다. 지난 포스팅에서 AsyncTask 를 배웠으니 AsynTask 를 사용해서 프로그램을 만들어 보겠습니다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.example.downloadimg;
 
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
 
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ImageView;
 
public class MainActivity extends Activity {
 
    
    ImageView imView;
    String imgUrl = "http://dnllab.incheon.ac.kr/appimg/";
    Bitmap bmImg;
    back task;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        task = new back();
        
        
        
        imView = (ImageView) findViewById(R.id.imageView1);
        
        task.execute(imgUrl+"img1");
        
        
    }
    
    
    private class back extends AsyncTask<String, Integer,Bitmap>{
        
 
 
        @Override
        protected Bitmap doInBackground(String... urls) {
            // TODO Auto-generated method stub
            try{
                URL myFileUrl = new URL(urls[0]);
                HttpURLConnection conn = (HttpURLConnection)myFileUrl.openConnection();
                conn.setDoInput(true);
                conn.connect();
                
                InputStream is = conn.getInputStream();
                
                bmImg = BitmapFactory.decodeStream(is);
                
                
            }catch(IOException e){
                e.printStackTrace();
            }
            return bmImg;
        }
        
        protected void onPostExecute(Bitmap img){
            imView.setImageBitmap(bmImg);
        }
        
    }
}
 




저는 back이라는 클래스를 만들어서 AsyncTask 를 extend했습니다. AsyncTask 의 첫 번째 generic 은 백그라운드 작업을 담당하는 메소드인 doInBackground 에 넘길 generic 으로 그림의 주소 값을 가지고 있는 String을 넣었습니다. 가운데 generic은 onProgressUpdate 메소드를 위한 generic인데 사용하지 않아서 그냥 Integer를 넣었습니다. Void를 넣어도 상관없습니다. 마지막 generic은 doInBackground 메소드가 끝나고 반환하는 generic으로 비트맵 타입을 넣었습니다.


이렇게 되면 doInBackground 메소드는 그림파일의 주소가 있는 String타입의 인자값을 받아와서 그림파일을 bitmap형식으로 반환하게 됩니다. bitmap 형식으로 반환하도록 설정한 이유는, 메인스레드가 아닌 다른 스레드에서 UI 객체에 접근할 수 없기 때문입니다. 만약 bitmap을 반환하지 않고 doInBackground 에서 바로 UI 객체에 접근해 뷰.setImage 등을 사용하여 변화시키려 한다면 에러가 발생합니다. 따라서 메인쓰레드에서 실행되는 onPostExecute 메소드를 통해 그림파일을 전달해서 UI객체에 접근하는 방법을 사용합니다.



onPostExecute 메소드를 보면 인자값으로 Bitmap img 가 되어있는 것을 확인할 수 있습니다. onPostExecute 는 메인 스레드에서 실행되기 때문에 imView.setImageBitmap 을 사용하여 UI 객체에 접근이 가능합니다. 실질적으로 이미지를 변경하는 부분은 이 부분이라고 할 수 있습니다.


이렇게 back 클래스를 만들고 나서 메인클래스에서 back 클래스의 객체를 만들고 execute 메소드를 사용하면 asynctask 를 사용할 수 있습니다.


List of Articles
번호 제목 날짜 조회 수
177 Android 와 JSP 간 파라미터 암복호화 (1) file 2016.05.26 7474
176 알아놓으면 좋은 내용정리 2016.06.07 7458
175 URL을 이용해서 이미지 다운로드 하기 2015.07.16 7400
174 prepend(),append(),before(),after() 메서드 2014.10.20 7361
173 [안드로이드] 콘텍스트 메뉴 사용예제 file 2015.09.03 7344
172 폰갭(PhoneGap) 플러그인 사용하기 2015.06.29 7332
171 안드로이드 ( Android ) APK 파일 생성하기 file 2015.07.17 7305
170 푸쉬 알림 기능. GCM (Google Cloud Messaging) 사용하기 (2) file 2015.07.16 7292
169 [안드로이드] 뷰(View)에 여백넣기 file 2015.07.17 7225
168 XmlPullParser 를이용하여 데이터 가져와보기!! 2014.08.28 7221
167 [안드로이드스튜디오] 단축키 2015.07.02 7160
166 [안드로이드] 뷰(View)의 너비와 높이 지정하기 file 2015.07.17 7140
165 네트워크 연결 상태 및 3G/WIFI 연결상태 체크하기 2016.03.18 7131
164 Invalid project description 문제 file 2015.07.01 7117
163 이미지 버튼(ImageButton) 만들기 2015.07.16 7111
162 안드로이드 스튜디오 자동 임포트 하기 file 2015.07.09 7107
161 [안드로이드] 레이아웃의 기본2 file 2015.07.16 7071
160 인텐트를 이용한 Activity간 데이터 전달 (사용자 정의 클래스) file 2015.07.16 7061
159 HTML5로 비디오 보여주기 Video Tag file 2014.09.04 7059
158 안드로이드 웹에서 이미지 불러오기!! 2014.08.28 7052
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

하단 정보를 입력할 수 있습니다

© k2s0o1d4e0s2i1g5n. All Rights Reserved