桌面小组件AppWidget - RemoteViews for widget update exceeds maximum bitmap memory usage

博文总结:

1.如果你的Widget是非频繁更新,才可以使用RemoteViews.setImageViewBitmap(viewId, bitmap) 来搞自己的这个小组件上的ImageView
2.如果你的Widget是会频繁更新的,请一定不要用setImageViewBitmap,必须要用setImageViewResource(viewId, resId)来设置ImageView

原因:

RemoteViews源码内部维护了一个:BitmapCache mBitmapCache, 每次你更新的bitmap进来,都会被缓存起来,最终计算RemoteViews占用内存大小的话,也会把这块算进去(没找到有可以释放BitmapCache的API),所以如果你看到这里,先检查下自己的API使用方式。

java.lang.IllegalArgumentException: RemoteViews for widget update exceeds maximum bitmap memory usage (used: 16482436, max: 15552000)
	at android.os.Parcel.createException(Parcel.java:2092)
	at android.os.Parcel.readException(Parcel.java:2056)
	at android.os.Parcel.readException(Parcel.java:2004)
	at com.android.internal.appwidget.IAppWidgetService$Stub$Proxy.updateAppWidgetProvider(IAppWidgetService.java:1175)
	at android.appwidget.AppWidgetManager.updateAppWidget(AppWidgetManager.java:771)
	at com.msxxxing.xxxxxx.updateWidget(WidgetUtil.kt:36)
	at com.msxxxing.xxxxxx.run(WidgetUpdateThread.kt:120)
Caused by: android.os.RemoteException: Remote stack trace:
	at com.android.server.appwidget.AppWidgetServiceImpl.updateAppWidgetInstanceLocked(AppWidgetServiceImpl.java:2413)
	at com.android.server.appwidget.AppWidgetServiceImpl.updateAppWidgetProvider(AppWidgetServiceImpl.java:2040)
	at com.android.internal.appwidget.IAppWidgetService$Stub.onTransact(IAppWidgetService.java:535)
	at android.os.Binder.execTransactInternal(Binder.java:1056)
	at android.os.Binder.execTransact(Binder.java:1029)

issue:
RemoteViews for widget update exceeds maximum bitmap memory usage (used: 16482436, max: 15552000)

root casue:
由于remoteviews是跨进程的传输,并不是传统意义上的view,因此当你ImageView去setImageBitmap的时候,需要注意你设置进去的bitmap是否超过了大小限制。

最大的Size公式为:
The total Bitmap memory used by the RemoteViews object cannot exceed that required to fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.

void computeMaximumWidgetBitmapMemory() {
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getRealSize(size);
        // Cap memory usage at 1.5 times the size of the display
        // 1.5 * 4 bytes/pixel * w * h ==> 6 * w * h
        mMaxWidgetBitmapMemory = 6 * size.x * size.y;
    }

系统内部AppWidgetServiceImpl.java中会去评估你给Remoteviews设置的view的大小,来看是否给你抛一个异常

if (views != null) {
            bitmapMemoryUsage = views.estimateMemoryUsage();
        }
        if (bitmapMemoryUsage > mMaxWidgetBitmapMemory) {
            throw new IllegalArgumentException("RemoteViews for widget update exceeds maximum" +
                    " bitmap memory usage (used: " + bitmapMemoryUsage + ", max: " +
                    mMaxWidgetBitmapMemory + ") The total memory cannot exceed that required to" +
                    " fill the device's screen once.");
        }

Solution:

Bitmap要压缩再使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值