본문 바로가기

나의 플랫폼/안드로이드

[ Android ] Thumnails를 사용 시 메모리 오류.

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
GridView를 이용하여 갤러리에 있는 이미지를 가져올 때 , 
Thumnails를 자주 사용하는데요.

용량도 적을 뿐더러, 알아서 알맞게 짤라주는 구글의 센스??ㅋㅋ
우선 제가 사용한 방법은 다음과 같습니다.

GridView에서 사용하는 BaseAdapter 안에 존재하는 getView 속!

public View getView(final int position, View convertView, ViewGroup parent) {

RelativeLayout img_template = null;

ImageView imgView = null;

CheckBox cbCheck = null;

Long id = mImgList.get(position);
 

if( convertView == null){

// 기본 레이아웃 형태를 가져온다.

LayoutInflater inflater = 
                (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

img_template =  (RelativeLayout)inflater.inflate(R.layout.img_temp, null);

imgView = (ImageView) img_template.findViewById(R.id.ImgView);

cbCheck = (CheckBox) img_template.findViewById(R.id.CBView);

// 표시할 이미지를 가져온다.(ID를 이용)

Bitmap bmp = Images.Thumbnails.getThumbnail(mContentResolver,

id, 

Images.Thumbnails.MICRO_KIND, null);

imgView.setImageBitmap(bmp);

// 선택이 되어 있으면 true로 변경

if(mSelectedImgList.indexOf(id) != -1){

cbCheck.setChecked(true);

}


          return img_template;

}else{

return convertView;

}

}

 저 빨간 부분이 제가 애기하고자 하는 문제점인 부분입니다.

처음 사용할 때는 문제가 없이 깔끔하게 작은 메모리로 썸네일 사진을 출력해주는데요.

이렇게 사진으로 받은 bmp의 메모리가

Activity가 종료되어도 사라지지 않는 겁니다.
 

당연 모든 bmp를 초기화 해줬죠! onDestory함수내에

-- bmp초기화 방법--
bmp.recycle();
bmp = null;


이 뿐만 아니라 Adapter내에 존재하는 모든 뷰들 초기화 삭제하거나
여러 가지 실험을 해봐도 메모리가 줄지 않고 쌓이더라구요. 

원인은 Thumnasils로 받게 되면 bitmap을 초기화해도 메모리를 계속 차지하더라구요..-0-;;

확인 방법 : http://gogorchg.tistory.com/entry/Android-HeapSize%ED%99%95%EC%9D%B8

한 3일 고생하다 찾은 이 Thumnails의 문제점..

결국 직접 사진을 줄이고 짤라서 Thumnails이미지를 만들었습니다.

로딩 시간은 더 걸리지만, 메모리 부화도 없어지고 메모리 차지하는 부분도 사라졌습니다. 

 
직접 만든 썸네일 소스입니다.
사용하실 분은 복사해서 쓰세요^^. 난 프리하니깐 ㅋ

               Uri uri = ContentUris.withAppendedId(Images.Media.EXTERNAL_CONTENT_URI,fileId);

Bitmap bitmap = null;

try{


InputStream stream = mContext.getContentResolver().openInputStream(uri);

BitmapFactory.Options options = new BitmapFactory.Options();

options.inPurgeable = true;

if(isThumnails){

options.inSampleSize = 6;

}else{

options.inSampleSize = 2;

}

options.inPurgeable = true;

options.inDither = true;

options.inPreferredConfig = Bitmap.Config.RGB_565;

bitmap = BitmapFactory.decodeStream(stream,null,options);


if(isThumnails){

float scale = 0;

if(bitmap.getWidth() > bitmap.getHeight()){

scale =  100.0f/bitmap.getWidth();

if(bitmap.getHeight() * scale < 100){

scale = 100.0f/bitmap.getHeight();

}

}else{

scale = 100.0f/bitmap.getHeight();

if(bitmap.getWidth() * scale < 100){

scale = 100.0f/bitmap.getWidth();

}

}

int pX = (int)(bitmap.getWidth()*scale);

int pY = (int)(bitmap.getHeight()*scale);

Bitmap resize = Bitmap.createScaledBitmap(bitmap,pX,pY, true);

Bitmap sliceBmp = Bitmap.createBitmap(resize, (pX/2)-50, (pY/2)-50, 100, 100);
 

bitmap.recycle();

bitmap = null;

resize.recycle();

resize = null;

stream.close();

return sliceBmp;

}

}catch(Exception e){

e.printStackTrace();

}

 
사이즈는 100*100으로 잡았습니다. DSLR로 촬영한 이미지 같은 경우는 제법 시간 걸리더라구요.^^;
참고하세요^^

그럼 오늘도 즐코딩!