안녕하세요
여러 데이터를 파싱해
100개의 이미지 url을 비트맵으로 변환하여 coverFlow(갤러리)로 뿌려줍니다.
순서
이미지 URL에서 이미지 비트맵으로 변환
변환한 이미지를 갤러리클래스로 보냄
받은 이미지를 바다에 반정도 반사되게 효과를 내어 이미지를 만듬
getView해서 이미지를 넣어줌.
coverflow에는 100개정도의 앨범이 들어갑니다.
근데 이미지 사이즈는 별로 안큰데요
카테고리 옮겨다니면서 많이 시도하다보면 outOfMemory에러가 나더라고요..
onDestroy 에 어댑터도 널시키고
스레드도 멈추게하고 System.gc(); 도하고 그랬거든요...
recycle은 안해줬는데요 이유는 어느 부분에 해줘야 할지 모르곘어요
이곳 저곳 넣어봤는데 에러가 나서요 ㅠㅠ
예외처리를 걸어도 안되더라고요 ㅠ
사이즈도 최대한 안깨지게 줄인건데...
왜이럴까요
해결책 팁 좀 부탁드립니다.
public Bitmap getBitmap(String url) {
// I identify images by hashcode. Not a perfect solution, good for the
// demo.
String filename = String.valueOf(url.hashCode());
File f = new File(cacheDir, filename);
// from SD cache
Bitmap b = decodeFile(f);
if (b != null){
return b;
}
// from web
try {
Bitmap bitmap = null;
InputStream is = new URL("url).openStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
return bitmap;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
// decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
try {
// decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// Find the correct scale value. It should be the power of 2.
final int REQUIRED_SIZE = 70;
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale =1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
}
return null;
}
이런식으로 해주는데도 그러네요 ㅜㅜ
public boolean createReflectedImages() {
final int reflectionGap = 2;
int index = 0;
for (Bitmap originalImage: mBit) {
int width = originalImage.getWidth();
int height = originalImage.getHeight();
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);
bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Config.ARGB_8888);
options.inPurgeable = true;
options.inDither = false;
options.inInputShareable = true;
options.inTempStorage = new byte[32*1024];
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
// Draw in the gap
Paint deafaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap,
deafaultPaint);
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0,
bitmapWithReflection.getHeight() + reflectionGap,
0x70ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
imageView = new ImageView(mContext);
imageView.setImageBitmap(bitmapWithReflection);
if (iDpi==160) {
imageView.setLayoutParams(new CoverFlow.LayoutParams(72, 130));
imageView.setScaleType(ScaleType.CENTER_INSIDE);
}else if (iDpi==320) {
if (iDpiwidth==800) {
imageView.setLayoutParams(new CoverFlow.LayoutParams(180, 235));
}else{
imageView.setLayoutParams(new CoverFlow.LayoutParams(180, 225));
}
imageView.setScaleType(ScaleType.FIT_XY);
}else{
if (iDpiwidth==540) {
imageView.setLayoutParams(new CoverFlow.LayoutParams(110, 164));
imageView.setScaleType(ScaleType.FIT_XY);
}else{
imageView.setLayoutParams(new CoverFlow.LayoutParams(110, 154));
imageView.setScaleType(ScaleType.FIT_XY);
}
}
mImages[index++] = imageView;
}
return true;
}
이렇게 넣어주고 getView에서
public View getView(int position, View convertView, ViewGroup parent) {
BitmapDrawable drawable = (BitmapDrawable) mImages[position]
.getDrawable();
drawable.setAntiAlias(true);
// return i;
return mImages[position];
}
이렇게 리턴 시켜주는데 어느부분에 recycle이랑 null을 넣어야될지 모르겠어여 다 에러가나요 ㅠㅠㅠ
2. BitmapFactory.decode...(url, bitmap.option) 에서 option 을 활용하세요
저는옵션애 약간의 연산을 해서 해상도애 맞는 최적의 이미지로 리사이징해서 이미지용량을 줄입니다.
3. 바로 url 에서 읽어오지말고파일로 저장했다가 필요할때만 거내서 쓰는전략으로 가세요. 그래야 최대한 메모리활용이 가능합니다