-4

我有应用程序,可以从相机获取照片并在 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() 什么都没有。

4

3 回答 3

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();
        }
    }
于 2013-07-23T10:01:08.067 回答
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);

}

PS:-我在某处读到的这个 decodeUri 方法不是我的代码。干杯!!

于 2013-07-23T10:00:01.353 回答
0

使用 imageloader 类。这将解决位图内存不足异常问题。

http://www.androidhive.info/2012/07/android-loading-image-from-url-http/

于 2013-07-23T10:00:35.077 回答