如何正确更新 AppWidget?
Posted
技术标签:
【中文标题】如何正确更新 AppWidget?【英文标题】:How Do I Properly Update AppWidget? 【发布时间】:2013-02-07 01:18:54 【问题描述】:我是 android 的菜鸟,我在更新 appwidget 时遇到了问题。这是一个新闻小部件,每 20 秒显示不同的文本。初始化小部件时,让文本正确切换和显示没有问题。但是,每 30 分钟更新一次小部件后,我的 widgetID int 数组会保留更新前存在的 int。因此,每次更新后,小部件都会显示旧数据和新数据。在更新过程中是否有清除旧数据的小部件 ID int 数组。非常感谢任何帮助。
我的代码:
allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
在小部件中切换文本的方法。这最初工作正常,但更新后显示旧数据和新数据......
public void updateStory()
tickerheadline = RssReader.rssheadline.get(storyCounter);
tickerstory = RssReader.rssstory.get(storyCounter);
remoteViews.setTextViewText(R.id.headline, tickerheadline );
remoteViews.setTextViewText(R.id.story, tickerstory );
if (storyCounter==RssReader.rssheadline.size()-1)
storyCounter = 0;
storyCounter++;
else
storyCounter++;
appWidgetManager.updateAppWidget(allWidgetIds, remoteViews);
//Log.e("Widget", allWidgetIds.toString());
mHandler.postDelayed(new Runnable()
public void run()
updateStory();
,20000);
编辑
public void updateStory()
//Added
appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
ComponentName thisWidget = new ComponentName(getApplicationContext(),MyWidgetProvider.class);
remoteViews = new RemoteViews(this.getApplicationContext().getPackageName(),R.layout.widget1);
tickerheadline = RssReader.rssheadline.get(storyCounter);
tickerstory = RssReader.rssstory.get(storyCounter);
remoteViews.setTextViewText(R.id.headline, tickerheadline );
remoteViews.setTextViewText(R.id.story, tickerstory );
if (storyCounter==RssReader.rssheadline.size()-1)
storyCounter = 0;
storyCounter++;
else
storyCounter++;
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
//appWidgetManager.updateAppWidget(allWidgetIds, remoteViews);
//Log.e("Widget", allWidgetIds.toString());
mHandler.postDelayed(new Runnable()
public void run()
updateStory();
,20000);
【问题讨论】:
也许如果你设置 else storyCounter++; to storyConter=0;会成功的。 感谢您的回复。这将如何防止显示以前的 widgetid 数据? 我以前从未使用过小部件,但我经常使用位图。当我想重置某些位图时,我会调用 bmp = null;我不确定你想在那里做什么。但是你打电话给storyCounter++;当故事计数器=0;并在您的 else 声明中。这意味着你清除了你的 storyCounter = 0;然后你调用了storyCounter++;为什么要这么做 ?从逻辑上讲,在您的 if else 语句中,您必须做不同的事情,但在您的语句中,您要做两次相同的事情。 我使用计数器来跟踪我从数组列表中提取的字符串。当我将它重置为零,然后重新启动计数器时,我确保在达到数组列表中的最后一个值后文本会不断切换。 【参考方案1】:虽然在更新等方面你可以非常聪明地使用 android 中的 AppWidgets,但最简单的方法是每次刷新时重新构建小部件内容。由于您仅每 30 分钟刷新一次,因此无需担心 CPU 使用率。
因此,我建议您每次使用标准方法触发更新时进行标准重建。您上面的代码虽然看起来正确,但实际上并不强制更新,从头开始更干净。一旦它起作用了,那么如果你能让它更轻量级,请告诉我如何做!
// You need to provide:
// myContext - the Context it is being run in.
// R.layout.widget - the xml layout of the widget
// All the content to put in it (duh!)
// Widget.class - the class for the widget
RemoteViews rv= new RemoteViews(myContext.getPackageName(), R.layout.widget);
rv.setXXXXXXX // as per normal using most recent data set.
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(myContext);
// If you know the App Widget Id use this:
appWidgetManager.updateAppWidget(appWidgetId, rv);
// Or to update all your widgets with the same contents:
ComponentName projectWidget = new ComponentName(myContext, Widget.class);
appWidgetManager.updateAppWidget(projectWidget, rv);
通常最简单的方法(在我看来)是将其包装在一个 WidgetUpdater.class 中,您可以从服务调用或直接使用时间警报调用。使用 onUpdate 通常是一个坏主意,因为它会强制手机进入全功率模式并且不是很可控。我从来没有设法让它工作。更好的做法是:
Intent myIntent = // As per your onUpdate Code
alarmPendingIntent = PendingIntent.getService(context, 0, myIntent, PendingIntent.FLAG_ONE_SHOT);
// ... using the alarm manager mechanism.
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, nextUpdateTimeMillis, alarmPendingIntent);
【讨论】:
感谢您的建议。我已经在我的小部件提供程序类的 onUpdate 方法中更新了我的小部件。请检查我的编辑,看看我是否正确处理。 我已经扩展了答案以尝试澄清我为什么提出不同的方法 - 如果仍然不清楚,请说。 你现在整理好了吗? 不幸的是,它仍然给我带来了麻烦,所以我决定只使用自动收报机而不是切换文本。不过还是谢谢以上是关于如何正确更新 AppWidget?的主要内容,如果未能解决你的问题,请参考以下文章
Android开发5:应用程序窗口小部件App Widgets的实现
ANDROID_MARS学习笔记_S02_006_APPWIDGET3_AppWidget发送广播及更新AppWidget