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

时间:2012-07-03 13:58:41

标签: android

我的代码有问题: (错误在代码下面)

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); 

  }
}

错误是:

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)

1 个答案:

答案 0 :(得分:0)

您的问题很简单:您一次显示太多图片。

您的解决方案可以通过多种方式完成:)

你可以像google play一样,只显示一些图像,当用户“靠近”它们时下载新图像并慢慢丢弃内存中的旧图像。也可以是下一页按钮等来加载下一张图像。

一般情况下,请避免显示太多位图并记住回收/丢弃/旧位图(通常系统会为您执行此操作,但不会列入长列表等。)

修改: 您可以查看支持库提供的googles lru cache。以下链接解释了lru缓存如何工作以及有关位图使用的其他非常重要的事情:link

但是整个这个主题实际上非常复杂;(我建议你调查googles shelves sample(这很难理解,但如果你能管理它,你真的会学到一个很多)。

使用lru缓存以及仅在需要时(在getview / bindview等中)获取图像可能对您有用。