简体   繁体   English

方法MediaStore.Images.Media.getBitmap(cr,uri); 返回位图大小超出VM预算

[英]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. 您可以像Google Play一样,仅显示一些图像,当用户“靠近”它们时下载新图像,然后慢慢从内存中丢弃旧图像。 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. 编辑 :您可以查看支持库提供的google lru缓存。 Following link explains how lru cache works and other very important things about bitmap usage: link . 以下链接说明了lru缓存的工作方式以及有关位图使用的其他非常重要的事情: 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). 但是整个主题实际上很难正确完成;(我建议您研究一下Google货架样本 (这很难理解,但是如果您能进行管理,那么您将学到很多东西)。

Using the lru cache together with getting the images only when they are needed (in getview/bindview etc.) would probably work for you. 将lru缓存与仅在需要时获取图像(在getview / bindview等中)一起使用可能对您有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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