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

Posted 胖虎

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了桌面小组件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要压缩再使用

以上是关于桌面小组件AppWidget - RemoteViews for widget update exceeds maximum bitmap memory usage的主要内容,如果未能解决你的问题,请参考以下文章

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

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

uniapp 窗口小工具桌面小部件微件 Ba-AppWidget

uniapp 窗口小工具桌面小部件微件 Ba-AppWidget

Android桌面小部件AppWidget开发

AppWidget(桌面小部件)