我有应用程序,我从相机获取照片并在imageview中显示它。
Uri bitmapPictureUri = intent.getParcelableExtra(TaskActivity.PHOTO);
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), bitmapPictureUri);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int nh = (int) (bitmap.getHeight() * (512.0 / bitmap.getWidth()));
bitmapPicture = Bitmap.createScaledBitmap(bitmap, 512, nh, true);
WeakReference<Bitmap> bm = new WeakReference<Bitmap>(bitmap);
WeakReference<Bitmap> bm2 = new WeakReference<Bitmap>(bitmapPicture);
picture.setImageBitmap(bm2.get());
一切正常,直到我改变方向。当我第一次改变时没关系,但是当我再次旋转时,我得到了永远的记忆:
07-23 11:43:18.840: E/AndroidRuntime(12024): FATAL EXCEPTION: main
07-23 11:43:18.840: E/AndroidRuntime(12024): java.lang.OutOfMemoryError
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:529)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:601)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:803)
07-23 11:43:18.840: E/AndroidRuntime(12024): at PhotoController.onCreate(PhotoController.java:117)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.app.Activity.performCreate(Activity.java:5104)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3692)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.app.ActivityThread.access$700(ActivityThread.java:141)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1240)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.os.Handler.dispatchMessage(Handler.java:99)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.os.Looper.loop(Looper.java:137)
07-23 11:43:18.840: E/AndroidRuntime(12024): at android.app.ActivityThread.main(ActivityThread.java:5039)
07-23 11:43:18.840: E/AndroidRuntime(12024): at java.lang.reflect.Method.invokeNative(Native Method)
07-23 11:43:18.840: E/AndroidRuntime(12024): at java.lang.reflect.Method.invoke(Method.java:511)
07-23 11:43:18.840: E/AndroidRuntime(12024): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
07-23 11:43:18.840: E/AndroidRuntime(12024): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
07-23 11:43:18.840: E/AndroidRuntime(12024): at dalvik.system.NativeStart.main(Native Method)
任何想法如何才能避免这个问题?我尝试使用simpleSize,weakreferences,bitmap.recycle。 System.gc(),没什么。
答案 0 :(得分:1)
我通过以下方式解决了我的问题:
protected void onDestroy() {
super.onDestroy();
bitmapPicture.recycle();
bitmap.recycle();
unbindDrawables(findViewById(R.id.picture_measure_picture));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
答案 1 :(得分:0)
我在这里是怎么做的。您必须使用我在下面添加的decodeUri方法从URI获取位图。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if(data != null){
Uri dataUri = data.getData();
Bitmap bitmap;
try {
bitmap = decodeUri(dataUri);
imageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
此方法将优化内存,您的异常将永远不会再次发生。
private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 140;
// Find the correct scale value. It should be the power of 2.
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(getContentResolver().openInputStream(selectedImage), null, o2);
}
P.S: - 我在SO上读到的这个decodeUri方法,不是我的代码。干杯!!
答案 2 :(得分:0)
使用imageloader类。这将解决位图内存异常问题。
http://www.androidhive.info/2012/07/android-loading-image-from-url-http/