-4

カメラから写真を取得してイメージビューで表示するアプリケーションがあります。

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

これが私がやっている方法です。URI からビットマップを取得するには、以下に追加した decodeUri メソッドを使用する必要があります。

    @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:- SO のどこかで読んだこの 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 に答える