티스토리 뷰
안녕하세요 박스여우입니다. 최근 언론사의 웹사이트와 앱을 제작중인데요, 언론사 애플리케이션 특성상 기사마다 이미지가 반드시 하나쯤은 있고, 그 기사들과 이미지들을 불러와 화면에 뿌려줘야 합니다.
하지만, 많은 이미지를 다루다 보니 [dalvikvm-heap: Out of memory on a 772812-byte allocation] 요런 에러, Out Of Memory - OOM이 발생하더군요
■ 메모리 정리?
원인은 Android 상에서 제공되는 메모리(heap)는 정해저 있지만, 제가 많은 이미지를 사용한 관계로 메모리가 부족한 상황이 발생한 것입니다. 이 때, 메모리를 정리한답시고 사용하지 않는 객체에 null을 지정해 준다고 한들 해당 객체의 메모리가 정리되는게 아니고 정리될 후보가 되는것 입니다.
이 대신 Bitmap을 모두 사용한 뒤에는 bitmap.recycle()을 통해 메모리를 바로바로 해제할 수 있습니다.
■ 이미지 크기문제!
하지만 저의경우는 url로 부터 이미지를 다운받아 ImageView에 그려주게 되는데, 받아오는 이미지가 너무 큰게 원인이되어 OOM이 발생하였습니다. 제가 기사로부터 이미지를 얻어오는 소스는 다음과 같습니다.
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 | public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { ImageView imageView; public DownloadImageTask(ImageView imageView) { this.imageView= imageView; } protected Bitmap doInBackground(String... urls) { String urlStr = urls[0]; Bitmap image = null; try { URL url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.connect(); InputStream in = connection.getInputStream(); image = BitmapFactory.decodeStream(in); } catch (Exception e) { e.printStackTrace(); } return image; } protected void onPostExecute(Bitmap result) { imageView.setImageBitmap(result); } } | cs |
전달받은 이미지 URL을 받고 URLConnection을 통해 inputStream을 열어 BitmapFactory를 이용해 최종적으로 Bitmap 이미지로 만들게 됩니다.
하지만, 위와같은 코드를 이용하여 많은 이미지를 다루게 되면 저처럼 OOM이 발생하게 됩니다. 이미지 사이가 어떻든 그 크기 그대로 받아오게 되기 때문이죠.
받아오는 이미지의 용량을 줄이기 위해 BitmapFactory.Options를 통해 이미지의 사이즈를 줄여서 받아올 수 있습니다(비록 해상도가 낮아지긴 하지만..) 아래는 BitmapFactory Option을 적용한 코드 입니다.
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 | public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { ImageView imageView; public DownloadImageTask(ImageView imageView) { this.imageView= imageView; } protected Bitmap doInBackground(String... urls) { String urlStr = urls[0]; Bitmap image = null; try { URL url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.connect(); InputStream in = connection.getInputStream(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize=2; } catch (Exception e) { e.printStackTrace(); } return image; } protected void onPostExecute(Bitmap result) { imageView.setImageBitmap(result); } } | cs |
inSampleSize=2; 옵션에서 이미지의 크기를 1/2배 줄이게 됩니다. 3을 주게 되면 1/3배가 되는것입니다. 이때 옵션을 짝수로 주면 연산이 더 빨라진다고 합니다...
'프로그래밍 > 안드로이드' 카테고리의 다른 글
Android - dp, 다양한 해상도 지원하기 (399) | 2017.06.11 |
---|---|
Android - 카카오링크를 사용해 컨텐츠 공유하기 (432) | 2016.08.18 |
Android ScrollView 스크롤이 바닥에 닿았을 때 자동 refresh (427) | 2016.08.18 |
Android AdMob 전면광고 달기 (403) | 2016.05.19 |
Android 6.0 - Permission 이용 런타임 권한 모델 (403) | 2016.05.12 |