如何有效地更新应用小部件

Posted

技术标签:

【中文标题】如何有效地更新应用小部件【英文标题】:How to efficiently update app widget 【发布时间】:2014-04-02 17:17:38 【问题描述】:

我正在开发一个音乐播放器。我想有效地更新小部件并避免java.lang.IllegalArgumentException: RemoteViews for widget update exceeds maximum bitmap memory usage 我的小部件有三个按钮(上一个,播放,下一个),进度条(显示曲目的当前位置)和图像视图(显示当前曲目的封面)。问题是我需要经常更新小部件(每秒显示进度)并且我经常得到 IllegalArgumentException。 请参阅下面的代码。简要说明:我将小部件视图存储在全局变量中(以获得更好的性能)。 startAlarm() - 启动警报管理器以每秒发送一次广播。 主要问题 - 如何提高性能并避免 IllegalArgumentException?

private static RemoteViews views;
@Override
    public void onReceive(Context context, Intent intent)
    
        super.onReceive(context, intent);

        String action = intent.getAction();
        AppWidgetManager wm = AppWidgetManager.getInstance(context);
        ComponentName cm = new ComponentName(context,SmallBiggerWidget.class);
        int[] ids = wm.getAppWidgetIds(cm);
        if(ids.length < 1)
            return;

        if(views == null)
            views = getViews(context);
        else if(action.equals(ACTION_TRACK_CHANGED))
            setNewAudioToView(context,views);
            setIconPlayToViews(views);
            setProgressTotView(views);
        else if(action.equals(ACTION_PAUSE) || action.equals(ACTION_PLAY))
            setIconPlayToViews(views);
        else if(action.equals(ACTION_PROGRESS_UPDATE))
            setProgressTotView(views);
        else if(action.equals(PlayingService.ACTION_RELOAD_IMAGE))
            setNewImageToView(PlayingService.audios.get(PlayingService.indexTrack),context,views);
        
       for(int id : ids)
                wm.updateAppWidget(id,views);
            
        if(isPlaying)
            startAlarm(context);
        else
            cancelAlarm(context);
        
    

IllegalArgumentException 的原因不是大封面(我将封面缩放为小尺寸),即使没有 imageView,我也会收到此错误;

【问题讨论】:

【参考方案1】:

我必须回答我自己的问题。 java.lang.IllegalArgumentException 的原因是静态变量 RemoteViews views 因为当我调用 views.setTextViewText(R.id.text,text) 这会将文本放入RemoteViews,但之前的文本不会被删除(RemoteViews 包含我给他的所有文本)。

如何避免这个问题?您应该每次都创建RemoteViews 的新实例。

如何提高性能?您应该只将您想要更改的内容放入RemoteViews 并调用wm.partiallyUpdateAppWidget(ids,views);

【讨论】:

我在 RemoteImageView 上设置位图时遇到了同样的问题,查看源代码我看到 RemoteView 有一个不断增长的 BitmapCache...感谢提示!

以上是关于如何有效地更新应用小部件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用来自 Activity 的数据更新小部件?

如何让我的 SwiftUI 小部件每分钟更新一次?

如何在午夜更新应用小部件?

如何创建具有配置活动的应用小部件,并首次对其进行更新?

Android BroadcastReceiver不更新小部件

如何在通知中心频繁更新今日小部件?