HomeScreen 重新启动后小部件冻结
Posted
技术标签:
【中文标题】HomeScreen 重新启动后小部件冻结【英文标题】:Widget frozen after HomeScreen restart 【发布时间】:2014-01-22 07:20:32 【问题描述】:我创建的小部件可以使用存储在 SharedPreferences 中的不同设置进行多次实例化。在配置活动(Multiple, configurable widgets - update issue)之后直接解决非更新小部件的初始问题后,一切似乎都工作正常。但。当主屏幕应用程序被杀死/重新启动时(在我的情况下,Trebuchet,android 4.3 和 4.2.2)小部件不会刷新并且 onClick 侦听器消失(不会触发 onUpdate 操作)。我只看到来自 xml 的具有默认、未更新布局的无响应、空 WigdetView。更奇怪的是 - 在手机重启或添加我的小部件的另一个实例之后 - 一切都恢复正常了。
我尝试了许多不同的方法来解决这个奇怪的问题(比如对 RemoteViews 的单一引用,使用 Service 而不是 AsyncTask 等) - 但这些想法都没有解决问题..
代码中有很多重要的逻辑,快捷键:
AppWidgetProvider:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
// ASYNCTASK WAY
new DownloadTask(context, appWidgetManager).execute("http://sampleurl/");
/*
// OR SERVICE WAY
// SERVICE LOGIC IS ALMOST THE SAME AS IN DownloadTask
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.startService(intent);
*/
@Override
public void onReceive(Context context, Intent intent)
Bundle extras = intent.getExtras();
int mAppWidgetId=0;;
if (extras != null)
mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
String action = intent.getAction();
if (action.equals("PreferencesUpdated"))
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
views.setViewVisibility(R.id.menuLayout, View.GONE);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
int[] appWidgetIds = new int[] mAppWidgetId;
onUpdate(context, appWidgetManager, appWidgetIds);
else if (action.equals("ShowMenu"))
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
views.setViewVisibility(R.id.menuLayout, View.VISIBLE);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
super.onReceive(context, intent);
下载任务
public DownloadTask(Context context, AppWidgetManager appWidgetManager)
this.context = context;
this.appWidgetManager = appWidgetManager;
@Override
protected String doInBackground(String... url)
// 1. DOWNLOAD FILE
// 2. PROCESS FILE, ADD TO DATABASE, ETC
// 3. UPDATE ALL WIDGETS
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds)
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
int myPref= settings.getInt("myPref"+widgetId, -1);
if(myPref!= -1)
Log.d("DownloadTask", "widget id:"+widgetId);
updateWidget(db, widgetId, selectedStation);
db.close();
return null;
@Override
protected void onPreExecute()
super.onPreExecute();
//SHOW PROGRESSBAR (LOADER) ON ALL WIDGETS
//ADD onClicks
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds)
views.setViewVisibility(R.id.progressLayout, View.VISIBLE);
views.setOnClickPendingIntent(R.id.linearLayout1, getMenuPendingIntent(context, widgetId));
views.setOnClickPendingIntent(R.id.refreshButton, getRefreshPendingIntent(context, widgetId));
views.setOnClickPendingIntent(R.id.settingsButton, getSettingsPendingIntent(context, widgetId));
appWidgetManager.updateAppWidget(widgetId, views);
@Override
protected void onPostExecute(String result)
super.onPostExecute(result);
//HIDE PROGRESSBAR (LOADER) ON ALL WIDGETS
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
views.setViewVisibility(R.id.progressLayout, View.INVISIBLE);
appWidgetManager.updateAppWidget(thisWidget, views);
if (exception)
Toast.makeText(context, context.getString(R.string.net_exc), Toast.LENGTH_LONG).show();
public void updateWidget(mysqliteHelper db, int widgetId, int myPref)
// UPDATE SINGLE WIDGET
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
views.setTextViewText(R.id.someText, "someText");
// ETC
appWidgetManager.updateAppWidget(widgetId, views);
我真的希望你们能帮助我,因为我被困住了。
ps。这是所有小部件一起刷新的预期行为。
【问题讨论】:
修改代码以一一更新小部件工作正常。但这不是令人满意的解决方案。 【参考方案1】:遇到类似问题后,我的小部件在重新启动启动器/主屏幕后无法正常工作,这里有一个可能的解决方案:
每当访问您的 RemoteViews 时,请再次设置.setOnClickPendingIntent(...)
。
所以基本上来说,在您修改RemoteViews
的onReceive()
中添加相应的行以添加PendingIntent
s,以及您可能修改这些的其他任何地方。
PS: 您可以放弃遍历所有 widgetIds 的 for 循环,然后使用
void AppWidgetManager.updateAppWidget(ComponentName provider, RemoteViews views)
一次更新所有视图。
【讨论】:
你刚才不让我跳出窗外。以上是关于HomeScreen 重新启动后小部件冻结的主要内容,如果未能解决你的问题,请参考以下文章