在调用getDrawable()方法时出现内存不足错误

4
我想获取Android设备上当前的壁纸图像,并在缩放后将其设置为我的列表中的图像视图。 我正在做的是这样的:
final WallpaperManager wm = WallpaperManager.getInstance(this);
final Drawable wallpaperDrawable = wm.getDrawable();
Bitmap bitmap = drawableToBitmap(wallpaperDrawable);
imageview.setImageBitmap(bitmap);

`drawableToBitmap`函数的代码如下:
public static Bitmap drawableToBitmap (Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable)drawable).getBitmap();
    }

    int width = drawable.getIntrinsicWidth();
    width = width > 0 ? width : 1;
    int height = drawable.getIntrinsicHeight();
    height = height > 0 ? height : 1;

    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}

但是我遇到了这个错误:
01-29 13:30:50.150: E/dalvikvm-heap(3281): Out of memory on a 3891216-byte allocation.
    01-29 13:30:50.160: I/dalvikvm(3281): "main" prio=5 tid=1 RUNNABLE
    01-29 13:30:50.160: I/dalvikvm(3281):   | group="main" sCount=0 dsCount=0 obj=0x409c0460 self=0x12810
    01-29 13:30:50.170: I/dalvikvm(3281):   | sysTid=3281 nice=0 sched=0/0 cgrp=default handle=1074082952
    01-29 13:30:50.180: I/dalvikvm(3281):   | schedstat=( 1725234737 955825527 142 ) utm=152 stm=20 core=0
    01-29 13:30:50.190: I/dalvikvm(3281):   at android.graphics.Bitmap.nativeCreate(Native Method)
    01-29 13:30:50.190: I/dalvikvm(3281):   at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
    01-29 13:30:50.190: I/dalvikvm(3281):   at android.graphics.Bitmap.createBitmap(Bitmap.java:585)
    01-29 13:30:50.190: I/dalvikvm(3281):   at android.app.WallpaperManager.generateBitmap(WallpaperManager.java:729)
    01-29 13:30:50.190: I/dalvikvm(3281):   at android.app.WallpaperManager$Globals.getCurrentWallpaperLocked(WallpaperManager.java:265)
    01-29 13:30:50.200: I/dalvikvm(3281):   at android.app.WallpaperManager$Globals.peekWallpaperBitmap(WallpaperManager.java:230)
    01-29 13:30:50.200: I/dalvikvm(3281):   at android.app.WallpaperManager.getDrawable(WallpaperManager.java:350)
    01-29 13:30:50.210: I/dalvikvm(3281):   at storeapps.com.profilechanger.ListActivity.onCreate(ListActivity.java:64)
    01-29 13:30:50.210: I/dalvikvm(3281):   at android.app.Activity.performCreate(Activity.java:4466)
    01-29 13:30:50.220: I/dalvikvm(3281):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
    01-29 13:30:50.220: I/dalvikvm(3281):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
    01-29 13:30:50.220: I/dalvikvm(3281):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
    01-29 13:30:50.220: I/dalvikvm(3281):   at android.app.ActivityThread.access$600(ActivityThread.java:123)
    01-29 13:30:50.220: I/dalvikvm(3281):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
    01-29 13:30:50.220: I/dalvikvm(3281):   at android.os.Handler.dispatchMessage(Handler.java:99)
    01-29 13:30:50.220: I/dalvikvm(3281):   at android.os.Looper.loop(Looper.java:137)
    01-29 13:30:50.230: I/dalvikvm(3281):   at android.app.ActivityThread.main(ActivityThread.java:4424)
    01-29 13:30:50.230: I/dalvikvm(3281):   at java.lang.reflect.Method.invokeNative(Native Method)
    01-29 13:30:50.230: I/dalvikvm(3281):   at java.lang.reflect.Method.invoke(Method.java:511)
    01-29 13:30:50.230: I/dalvikvm(3281):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    01-29 13:30:50.230: I/dalvikvm(3281):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    01-29 13:30:50.230: I/dalvikvm(3281):   at dalvik.system.NativeStart.main(Native Method)
    01-29 13:30:50.270: I/Process(570): Sending signal. PID: 3281 SIG: 3
    01-29 13:30:50.270: I/dalvikvm(3281): threadid=3: reacting to signal 3
    01-29 13:30:50.310: W/WallpaperManager(3281): Can't generate default bitmap
    01-29 13:30:50.310: W/WallpaperManager(3281): java.lang.OutOfMemoryError
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.graphics.Bitmap.nativeCreate(Native Method)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.graphics.Bitmap.createBitmap(Bitmap.java:585)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.WallpaperManager.generateBitmap(WallpaperManager.java:729)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.WallpaperManager$Globals.getCurrentWallpaperLocked(WallpaperManager.java:265)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.WallpaperManager$Globals.peekWallpaperBitmap(WallpaperManager.java:230)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.WallpaperManager.getDrawable(WallpaperManager.java:350)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at storeapps.com.profilechanger.ListActivity.onCreate(ListActivity.java:64)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.Activity.performCreate(Activity.java:4466)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.ActivityThread.access$600(ActivityThread.java:123)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.os.Handler.dispatchMessage(Handler.java:99)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.os.Looper.loop(Looper.java:137)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at android.app.ActivityThread.main(ActivityThread.java:4424)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at java.lang.reflect.Method.invokeNative(Native Method)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at java.lang.reflect.Method.invoke(Method.java:511)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    01-29 13:30:50.310: W/WallpaperManager(3281):   at dalvik.system.NativeStart.main(Native Method)
    01-29 13:30:50.310: D/ProfileChangerApp(3281):  wallpaper manager is :android.app.WallpaperManager@41085b88
    01-29 13:30:50.320: D/ProfileChangerApp(3281): image is not null
    01-29 13:30:50.320: I/dalvikvm(3281): Wrote stack traces to '/data/anr/traces.txt'
    01-29 13:30:50.340: D/AndroidRuntime(3281): Shutting down VM
    01-29 13:30:50.371: W/dalvikvm(3281): threadid=1: thread exiting with uncaught exception (group=0x409bf1f8)
    01-29 13:30:50.430: E/AndroidRuntime(3281): FATAL EXCEPTION: main
    01-29 13:30:50.430: E/AndroidRuntime(3281): java.lang.RuntimeException: Unable to start activity ComponentInfo{storeapps.com.profilechanger/storeapps.com.profilechanger.ListActivity}: java.lang.NullPointerException
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.app.ActivityThread.access$600(ActivityThread.java:123)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.os.Handler.dispatchMessage(Handler.java:99)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.os.Looper.loop(Looper.java:137)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.app.ActivityThread.main(ActivityThread.java:4424)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at java.lang.reflect.Method.invokeNative(Native Method)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at java.lang.reflect.Method.invoke(Method.java:511)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at dalvik.system.NativeStart.main(Native Method)
    01-29 13:30:50.430: E/AndroidRuntime(3281): Caused by: java.lang.NullPointerException
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at storeapps.com.profilechanger.ListActivity.onCreate(ListActivity.java:70)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.app.Activity.performCreate(Activity.java:4466)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
    01-29 13:30:50.430: E/AndroidRuntime(3281):     ... 11 more

Please help me !


1
嗨,朋友,请在将图像设置到ImageView之前压缩图像。 - Phuoc Huynh
@PankajNimgade 我尝试了这个,但还没有起作用, - beginner
@初学者,你需要做的是调整位图图像的大小,如果图像太大,你会遇到这个错误。这里有一个问题,你可以看到问问题的人正在将图像缩小 http://stackoverflow.com/questions/34661257/load-applications-icons-and-getting-outofmemory-exception-while-resizing/34661894#34661894 - Pankaj Nimgade
@初学者,您尝试渲染的图像大小是多少? - Pankaj Nimgade
@PankajNimgade 我正在尝试在我的列表中展示从当前壁纸中取出的图像,图像视图大小为8080,并且我还有一个文本视图.. 图像大小为12801440。 - beginner
显示剩余3条评论
5个回答

4

调整图像大小 位图

Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.yourImageName);

以上代码将从Drawable获取Bitmap。除了添加以上代码之外,无需进行任何操作即可从Drawable获取Bitmap。
int height = (bitmap.getHeight() * 512 / bitmap.getWidth());
Bitmap scale = Bitmap.createScaledBitmap(bitmap, 512, height, true);
imageView.setImageBitmap(scale);

我尝试了这个,但仍然得到相同的错误: final WallpaperManager wm = WallpaperManager.getInstance(this); final Drawable wallpaperDrawable = wm.getDrawable(); Bitmap bitmap = drawableToBitmap(wallpaperDrawable); int height = (bitmap.getHeight() * 512 / bitmap.getWidth()); Bitmap scale = Bitmap.createScaledBitmap(bitmap, 512,height, true); imageview.setImageBitmap(scale); - beginner
decodeResource需要图片的ID,但我已经从getDrawable中取出了可绘制图像。 - beginner
它可以工作,但消耗了大量的 CPU 资源,并且会导致卡顿。 - Stanislav Kinzl

2

你的Logcat报错信息是什么

01-29 13:30:50.310: W/WallpaperManager(3281): java.lang.OutOfMemoryError

当运行应用程序或虚拟机或设备内部函数请求的内存大小超出可用平台资源时,会抛出OutOfMemoryError。

  1. 在设置ImageView之前压缩图像

在可能的情况下,从现有位图中创建一个新的缩小的位图。 如果指定的宽度和高度与源位图的当前宽度和高度相同,则返回源位图,不会创建新的位图。

Bitmap.createScaledBitmap(YourImageBitMap, 100, 50, true);
  1. 减小图片大小

您可以阅读 如何处理OutOfMemoryError错误

在将图像加载到位图对象时出现奇怪的内存不足问题


2
请将不是矢量绘图的drawable放入DRAWABLE-NODPI而不是DRAWABLE中。否则,在某些设备上,它们会被缩放并具有更高的内存使用率,导致OOME错误。在三星设备上更容易发生。最初的回答。

1
Drawable wallpaper = getApplicationContext().getWallpaper();

wallpaper 是一个引用。

Bitmap.createBitmap 可能会导致 OOM 异常。

WindowManager 源代码:

// This is the final bitmap we want to return.
try {
Bitmap newbm = Bitmap.createBitmap(width, height,Bitmap.Config.ARGB_8888);

0
在你的清单应用标签中添加android:largeHeap="true"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接