Marshmallow上setImageResource()的OutOfMemoryError

时间:2018-05-03 14:19:51

标签: android imageview out-of-memory android-6.0-marshmallow

下载并放入我的项目时,我有ImageView为797x800。但是,它适合我的Activity上的ImageView,它跨越屏幕的宽度,大约是高度的一半。我正在使用名为PhotoViewcom.github.chrisbanes.photoview.PhotoView)的GitHub库,因此可以使用捏合手势缩放图像,但是在我切换到此库之前发生了崩溃并且只使用了正常{{1 }}

按下按钮后,会调用一个方法,该方法在ImageView中随机生成一个字符串,在使用处理程序进行50次调用后(每50毫秒),它会落在最后一个字符串上并相应地选择图像。再次单击该按钮时,它会将ImageView重置为原始按钮,并重复该循环。 switch语句中有30个图像可供选择,崩溃发生在TextView

我的问题是,我有什么选择为旧手机正确分配足够的内存来处理这个问题?我应该在将图像放入项目之前调整图像大小吗? Android版本不会发生崩溃报告> 6.0。

我的堆栈跟踪:

setImageResource(R.drawable.image_name_here)

正在发生的getMarker()方法:

java.lang.OutOfMemoryError: 
  at dalvik.system.VMRuntime.newNonMovableArray (Native Method)
  at android.graphics.BitmapFactory.nativeDecodeAsset (Native Method)
  at android.graphics.BitmapFactory.decodeStream (BitmapFactory.java:856)
  at android.graphics.BitmapFactory.decodeResourceStream (BitmapFactory.java:675)
  at android.graphics.drawable.Drawable.createFromResourceStream (Drawable.java:2228)
  at android.content.res.Resources.loadDrawableForCookie (Resources.java:4215)
  at android.content.res.Resources.loadDrawable (Resources.java:4089)
  at android.content.res.Resources.getDrawable (Resources.java:2005)
  at android.content.res.Resources.getDrawable (Resources.java:1987)
  at android.content.Context.getDrawable (Context.java:464)
  at android.widget.ImageView.resolveUri (ImageView.java:827)
  at android.widget.ImageView.setImageResource (ImageView.java:434)
  at com.github.chrisbanes.photoview.PhotoView.setImageResource (PhotoView.java:111)
  at com.company_name.my_app_name.MainActivity.getMarker (MainActivity.java:355)
  at com.company_name.my_app_name.MainActivity.access$100 (MainActivity.java:37)
  at com.company_name.my_app_name.MainActivity$4$2.run (MainActivity.java:226)
  at android.os.Handler.handleCallback (Handler.java:739)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:158)
  at android.app.ActivityThread.main (ActivityThread.java:7237)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1230)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1120)

我尝试使用

进行临时修复
private void getMarker(String text) {
    switch (text) {
        case "Image 1":
            photoView.setImageResource(R.drawable.image_name1); 
            break;
        case "Image 2":
            photoView.setImageResource(R.drawable.image_name_2);
            break;
        case "Image 3":
            photoView.setImageResource(R.drawable.image_name_3);
            break;
        case "Image 4":
            photoView.setImageResource(R.drawable.image_name_4);
            break;
        case "Image 5":
            photoView.setImageResource(R.drawable.image_name_5);
            break;
//25 more switch cases follow

在我的清单中无济于事。无论如何,我不希望这是一个永久的解决方案。

2 个答案:

答案 0 :(得分:3)

  

所有这些图片都在/ res / drawable /

将它们移至res/drawable-anydpi/res/drawable/res/drawable-mdpi/的同义词。大多数Android设备都有更高密度的屏幕,因此Android会对你的图像进行相当多的上采样,从而导致它们占用更多的内存。

答案 1 :(得分:0)

您需要回收旧的位图。 首先从资源创建一个位图,然后将此位图设置为imageView。之后,回收旧的位图。

    Bitmap newBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
Bitmap oldBitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
imageView.setImageBitmap(newBitmap);
oldBitmap.recycle();