Android 尝试加载 1 兆字节图像时抛出内存不足错误
Android throwing out of memory error when trying to load 1 megabyte image
相关代码:
runOnUiThread(new Runnable() {
@Override
public void run() {
ImageButton btn = (ImageButton) findViewById(R.id.info_image);
btn.setImageResource(currentID[currentIDPos]);
}
});
这是说 运行 方法正在分配 400 多兆字节。我的 jpg 大小不超过 1 兆字节。 运行() 方法每 3-4 秒左右在计时器上调用一次,然后在单击时调用,但这无关紧要,因为据我所知,使用 printlns 仅调用 运行()坠机前一次。
编辑:这是例外情况。必须再次 运行 才能得到这个,这次内存量不同但仍然很大。
FATAL EXCEPTION: main
Process: com.grey.handsaver, PID: 32531
java.lang.OutOfMemoryError: Failed to allocate a 215151564 byte allocation with 33554400 free bytes and 100MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:988)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2580)
at android.content.res.Resources.loadDrawable(Resources.java:2487)
at android.content.res.Resources.getDrawable(Resources.java:814)
at android.content.res.XResources.getDrawable(XResources.java:572)
at android.content.Context.getDrawable(Context.java:403)
at android.widget.ImageView.resolveUri(ImageView.java:747)
at android.widget.ImageView.setImageResource(ImageView.java:398)
at com.grey.handsaver.ExerciseInfoActivity.run(ExerciseInfoActivity.java:128)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5430)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:913)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:706)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)
尝试使用 picasso 库加载大型 image.it 具有内置缓存功能。
第 1 步:
首先在 gradle.build 中编写后续代码并同步 gradle.
compile 'com.squareup.picasso:picasso:2.5.2'
第 2 步:
Picasso.with(context).load("YOUR IMAGE PATH").into(btn);
并在我们加载 image.in 的地方编写上面的代码,您必须提供图像路径并确保图像路径是 valid.if 您真的想了解更多关于此库的信息访问 this.
我希望你对我的想法很清楚。
祝你好运
问题很可能是您没有清理之前分配的 space。你确定加载这些图片的 fragment/activity 也从 backstack 中删除了吗?或者也许图像本身没有被垃圾收集?
重新执行导致 OutofMemory 异常的相同步骤,但确保切换到 Android Studio 中的“内存监视器”选项卡,并检查内存在哪里急剧增加但没有在应该释放的时候释放。这应该让您抢先了解内存泄漏可能在哪里。
也有可能没有泄漏,而是你的图片本身很大(虽然看起来不是)。在这种情况下,您应该进行延迟加载、缓存实现等,或者只使用像 Picasso 这样的第三方库来为您处理这些问题
好的,我明白了。我使用的是 lg g4,它使用 xxxhdpi,我的图像位于可绘制文件夹中,而不是 drawable-xxxhdpi 文件夹中。这解决了我的问题,无需使用 picasso 或其他方法。
相关代码:
runOnUiThread(new Runnable() {
@Override
public void run() {
ImageButton btn = (ImageButton) findViewById(R.id.info_image);
btn.setImageResource(currentID[currentIDPos]);
}
});
这是说 运行 方法正在分配 400 多兆字节。我的 jpg 大小不超过 1 兆字节。 运行() 方法每 3-4 秒左右在计时器上调用一次,然后在单击时调用,但这无关紧要,因为据我所知,使用 printlns 仅调用 运行()坠机前一次。
编辑:这是例外情况。必须再次 运行 才能得到这个,这次内存量不同但仍然很大。
FATAL EXCEPTION: main
Process: com.grey.handsaver, PID: 32531
java.lang.OutOfMemoryError: Failed to allocate a 215151564 byte allocation with 33554400 free bytes and 100MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:988)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2580)
at android.content.res.Resources.loadDrawable(Resources.java:2487)
at android.content.res.Resources.getDrawable(Resources.java:814)
at android.content.res.XResources.getDrawable(XResources.java:572)
at android.content.Context.getDrawable(Context.java:403)
at android.widget.ImageView.resolveUri(ImageView.java:747)
at android.widget.ImageView.setImageResource(ImageView.java:398)
at com.grey.handsaver.ExerciseInfoActivity.run(ExerciseInfoActivity.java:128)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5430)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:913)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:706)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)
尝试使用 picasso 库加载大型 image.it 具有内置缓存功能。
第 1 步: 首先在 gradle.build 中编写后续代码并同步 gradle.
compile 'com.squareup.picasso:picasso:2.5.2'
第 2 步:
Picasso.with(context).load("YOUR IMAGE PATH").into(btn);
并在我们加载 image.in 的地方编写上面的代码,您必须提供图像路径并确保图像路径是 valid.if 您真的想了解更多关于此库的信息访问 this.
我希望你对我的想法很清楚。
祝你好运
问题很可能是您没有清理之前分配的 space。你确定加载这些图片的 fragment/activity 也从 backstack 中删除了吗?或者也许图像本身没有被垃圾收集? 重新执行导致 OutofMemory 异常的相同步骤,但确保切换到 Android Studio 中的“内存监视器”选项卡,并检查内存在哪里急剧增加但没有在应该释放的时候释放。这应该让您抢先了解内存泄漏可能在哪里。
也有可能没有泄漏,而是你的图片本身很大(虽然看起来不是)。在这种情况下,您应该进行延迟加载、缓存实现等,或者只使用像 Picasso 这样的第三方库来为您处理这些问题
好的,我明白了。我使用的是 lg g4,它使用 xxxhdpi,我的图像位于可绘制文件夹中,而不是 drawable-xxxhdpi 文件夹中。这解决了我的问题,无需使用 picasso 或其他方法。