HttpURLConnection이나 Volley 라이브러리를 이용하여 http 통신으로 서버로부터 데이터를 받아올 수 있다.
하지만 이미지의 경우 용량이 크기 때문에 다른 데이터와 구분하여 다른 방식으로 받는 것이 효율적이다.
따라서 이미지를 별도의 url로 전달받아 해당 url을 통해 별도로 다운로드하여 사용하게 된다.
요즘에는 이미지 파일을 다운로드 할 때 여러가지 편리한 기능을 제공하는 라이브러리들을 사용한다.
UniversalImageLoader 나 Glide 라이브러리를 사용하면 다운로드 및 캐싱까지 자동으로 처리해준다.
하지만 이 글에서는 기본적으로 제공되는 URL의 openConnection을 이용하여 직접 이미지를 다운로드하여,
BitmapFactory를 이용하여 Bitmap으로 변환하고, HashMap을 통해 직접 캐싱하는 방법을 알아보도록 한다.
Source Code
먼저 서버로부터 다운로드해야 하므로 메인 쓰레드가 아닌 AsyncTask로 분리하여 구현하였다.
AsyncTask에 대한 설명은 아래 글을 참고.
package com.juhy.myapplication;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;
import java.net.URL;
import java.util.HashMap;
public class ImageLoadTask extends AsyncTask<Void, Void, Bitmap> {
private String urlStr;
private ImageView imageView;
private static HashMap<String, Bitmap> bitmapHash = new HashMap<String, Bitmap>();
public ImageLoadTask(String urlStr, ImageView imageView){
this.urlStr = urlStr;
this.imageView = imageView;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(Void... voids) {
Bitmap bitmap = null;
try {
// 이미 url을 통해 불러온 적이 있다면 이전 bitmap을 삭제
if(bitmapHash.containsKey(urlStr)) {
Bitmap oldBitmap = bitmapHash.remove(urlStr);
if(oldBitmap != null){
oldBitmap.recycle();
oldBitmap = null;
}
}
URL url = new URL(urlStr);
bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
bitmapHash.put(urlStr, bitmap);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
imageView.setImageBitmap(bitmap);
imageView.invalidate();
}
}
ImageLoadTask()
생성자에서는 액티비티로부터 이미지를 받아올 url과 이미지를 띄울 ImageView를 받아오도록 한다.
doInBackground()
HashMap에 url을 key로 한 bitmap이 있다면 recycle()로 없앤다.
url로 서버와 연결한 뒤 InputStream을 BitmapFactory로 decode하여 bitmap 변수에 저장한다.
새 bitmap을 HashMap에 저장한다.
onPostExecute()
ImageView에 bitmap 이미지를 넣어준 뒤 최신화한다.
package com.juhy.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendImageRequest();
}
});
}
public void sendImageRequest(){
String url = "https://movie-phinf.pstatic.net/20161123_188/1479862185516tYkKO_JPEG/movie_image.jpg";
ImageLoadTask task = new ImageLoadTask(url, imageView);
task.execute();
}
}
MainActivity에서는 이미지를 받아올 AsyncTask에 url과 imageView를 넘겨준 뒤 실행해준다.
버튼 클릭 시 url로부터 정상적으로 이미지를 받아와 ImageView에 띄워주는 것을 볼 수 있다.
Reference
[부스트코스]안드로이드 프로그래밍
'Android > Concepts' 카테고리의 다른 글
SQLite DB에 데이터 저장하기 (0) | 2020.05.01 |
---|---|
Glide 라이브러리 사용법 (0) | 2020.04.30 |
Gson을 이용하여 Json 파싱하기 (0) | 2020.04.27 |
Volley 라이브러리 사용법 (0) | 2020.04.26 |
HttpURLConnection을 이용한 HTTP 통신 (0) | 2020.04.25 |