简体   繁体   中英

method MediaStore.Images.Media.getBitmap(cr, uri); returns bitmap size exceeds VM budget

I have a problem with this code: (The error is below the code)

public class ChooseImage extends Activity
{

private static final int DELETE_DIALOG = 1; 

private Gallery gallery = null; 

private int selectedImageId; 


  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState); 
       gallery = new Gallery(this); 
      Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 
      String[] projection = { MediaStore.Images.Media._ID }; 
      String selection = null; 
      String[] selectionArgs = null; 
      String sortOrder = null; 
      Cursor cursor = managedQuery(uri, projection, selection, selectionArgs, sortOrder); 

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

      gallery.setAdapter(new CursorAdapter(this, cursor, true) { 

        public View newView(Context context, Cursor cursor, ViewGroup parent) { 
                int id = cursor.getInt(0); 
                ContentResolver cr = getContentResolver(); 
                Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id); 
                Bitmap image = null; 

        try { 
            image = MediaStore.Images.Media.getBitmap(cr, uri); 
        } catch (Exception e) { 
         Log.e("Error", "Error", e); 
        } 

            ImageView imageView = new ImageView(context); 
            imageView.setId(id); 
            imageView.setScaleType(ScaleType.CENTER_INSIDE); 

            imageView.setImageBitmap(image); 
            return imageView; 
       }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // TODO Auto-generated method stub

        } 
      }); 

      LinearLayout linearLayout = new LinearLayout(this); 
      linearLayout.addView(gallery); 
      setContentView(linearLayout); 

  }
}

THE ERROR IS:

07-03 15:40:59.978: E/AndroidRuntime(887): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:469)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:525)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:712)
07-03 15:40:59.978: E/AndroidRuntime(887):  at com.entDan.imagefun.ChooseImage$1.newView(ChooseImage.java:58)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.widget.CursorAdapter.getView(CursorAdapter.java:182)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.widget.Gallery.makeAndAddView(Gallery.java:745)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.widget.Gallery.fillToGalleryRight(Gallery.java:697)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.widget.Gallery.trackMotionScroll(Gallery.java:372)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.widget.Gallery$FlingRunnable.run(Gallery.java:1366)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.os.Handler.handleCallback(Handler.java:587)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.os.Handler.dispatchMessage(Handler.java:92)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.os.Looper.loop(Looper.java:123)
07-03 15:40:59.978: E/AndroidRuntime(887):  at android.app.ActivityThread.main(ActivityThread.java:4627)
07-03 15:40:59.978: E/AndroidRuntime(887):  at java.lang.reflect.Method.invokeNative(Native Method)
07-03 15:40:59.978: E/AndroidRuntime(887):  at java.lang.reflect.Method.invoke(Method.java:521)
07-03 15:40:59.978: E/AndroidRuntime(887):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
07-03 15:40:59.978: E/AndroidRuntime(887):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
07-03 15:40:59.978: E/AndroidRuntime(887):  at dalvik.system.NativeStart.main(Native Method)

Your problem is simple: You display too many images at once.

Your solution can be done in many different ways :)

You could do like google play, only show some images, download new images when the user gets "near" them and slowly discard the old images from memory. Could also be a next page button etc. to load the next images.

In general avoid showing too many bitmaps and remember to recycle/discard/ old bitmaps (often the system does this for you, but not in a long list etc.).

Edit : You could look into googles lru cache which is available with the support library. Following link explains how lru cache works and other very important things about bitmap usage: link .

But whole this subject is actually pretty complex to do properly ;( I'd recommend that you look into googles shelves sample (which can be hard to understand, but if you can manage it, you'll really learn a lot).

Using the lru cache together with getting the images only when they are needed (in getview/bindview etc.) would probably work for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM