我目前正在处理我之前制作的小部件的更新,我遇到了小部件视图冻结的问题,或者它在一段时间后停止更新。
该应用程序是一个系统监视器,每秒更新一次(是的,我知道它经常更新它对电池寿命有害,但我设置了一些广播接收器来禁用更新以帮助这个显着),并且因为报警管理员不再允许每秒更新,我不得不使用一个处理程序和一个runnable来调用一个对象,该对象需要上下文来更新我们的远程视图和小部件。
它从创建和调用对象的提供者开始:
ProviderHelper.java
//Save our context
context = parentContext;
//creating Handler to update every second
handler = new Handler();
//Create our updater
updater = new WidgetUpdater(parentContext);
//Start our sleep receiver
registBroadcastReceiver(context);
//Set our quit to false
quit = false;
runUpdate = new Runnable() {
public void run() {
//Run our updates in the service
if(!ProviderHelper.isQuitting())
{
updater.runUpdate(context);
}
//Quit the handler
if(ProviderHelper.isQuitting()) {
//Remove all pending callbacks, and then return
handler.removeCallbacks(this);
return;
}
//Use post at time to only update when the phone is not in deep sleep :)
else handler.postAtTime(this, SystemClock.uptimeMillis() + updateInterval);
}
};
handler.post(runUpdate);
}
然后我们调用帮助器来更新小部件的指定部分
WidgetUpdater.java
public void update(Context context) {
Log.d("WIDGET UPDATER", "Updating...");
//call time methods, not calling if unchecked
if (timeMan.timeStatus()) timeMan.getTime();
//call system methods
if (battMan.percentStatus() || battMan.tempStatus()) {
battMan.getBatteryPercent(context);
battMan.getBatteryTemp(context);
}
if (cpuMan.cpuStatus()) cpuMan.getCpuUsage();
if (timeMan.upTimeStatus()) timeMan.getUptime();
//call memory methods
if (diskMan.memoryStatus()) diskMan.getSpace();
if (diskMan.ramStatus()) diskMan.getRam(context);
//call network methods
if (networkMan.typeStatus()) networkMan.getNetworkType(context);
if (networkMan.ipStatus()) networkMan.getIp(context);
if (networkMan.downSpeedStatus() || networkMan.upSpeedStatus()) networkMan.getSpeeds();
//update widget for all size
// Need to grab our views every single time
views = new RemoteViews(context.getApplicationContext().getPackageName(), R.layout.widget_layout);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(thiswidget, views);
manager.updateAppWidget(thiswidgetsmall, views);
manager.updateAppWidget(thiswidgetbig, views);
manager.updateAppWidget(thiswidgetbigger, views);
manager.updateAppWidget(thiswidgetsmallest, views);
//Try notifying the wifgets their data changed
//Yes this is redundant, I am trying everything to get this to work
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidget), views.getLayoutId());
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidgetsmall), views.getLayoutId());
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidgetbig), views.getLayoutId());
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidgetbigger), views.getLayoutId());
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidgetsmallest), views.getLayoutId());
}
例如,这是来自时间小部件帮助
的调用TimeHelper.java
//function for time
@SuppressLint("SimpleDateFormat")
public void getTime()
{
//time, creating date and inserting it to simple date format
Date date = new Date();
SimpleDateFormat time= new SimpleDateFormat("hh:mm:ss a");
SimpleDateFormat day = new SimpleDateFormat("EEEE, MMMM dd, yyyy");
if(shortBool) day = new SimpleDateFormat("EEE, MMM dd, yyyy");
else day = new SimpleDateFormat("EEEE, MMMM dd, yyyy");
//24 hour settings
if(hourFormat == true) time = new SimpleDateFormat("HH:mm:ss a");
else time = new SimpleDateFormat("hh:mm:ss a");
//setting text to time
views.setTextViewText(R.id.time, "Time: " + time.format(date));
views.setTextViewText(R.id.date, "Date: " + day.format(date));
}
我已经发布了这个,但这是我更新视图的方式:
WidgetUpdater.java(在上面发布的更新功能中)
//update widget for all size
// Need to grab our views every single time?
views = new RemoteViews(context.getApplicationContext().getPackageName(), R.layout.widget_layout);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(thiswidget, views);
manager.updateAppWidget(thiswidgetsmall, views);
manager.updateAppWidget(thiswidgetbig, views);
manager.updateAppWidget(thiswidgetbigger, views);
manager.updateAppWidget(thiswidgetsmallest, views);
//Try notifying the wifgets their data changed
//Yes this is redundant, I am trying everything to get this to work
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidget), views.getLayoutId());
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidgetsmall), views.getLayoutId());
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidgetbig), views.getLayoutId());
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidgetbigger), views.getLayoutId());
manager.notifyAppWidgetViewDataChanged(manager.getAppWidgetIds(thiswidgetsmallest), views.getLayoutId());
我尝试过这样的解决方案:
Android widget stops working after a while?
他们没有工作。如果你注意到,我每次调用更新函数时都会记录,其中调用AppWidgetManager来更新app小部件,所以我确信这一切都被调用了。在调用更新函数的意义上,小部件的远程视图不更新(如果不清楚)。任何关于小部件远程视图为什么会在一段时间(~5-10分钟)后停止更新的任何帮助都将非常感激。如果您需要更多信息,请告诉我们!
该项目也是开源的,因此您可以在此处查看所有代码:
https://github.com/torch2424/Stats-Monitor-Widget
谢谢!