AppWidgetManager在一段时间后停止更新其Remoteview

时间:2016-02-16 03:35:24

标签: java android widget

我目前正在处理我之前制作的小部件的更新,我遇到了小部件视图冻结的问题,或者它在一段时间后停止更新。

该应用程序是一个系统监视器,每秒更新一次(是的,我知道它经常更新它对电池寿命有害,但我设置了一些广播接收器来禁用更新以帮助这个显着),并且因为报警管理员不再允许每秒更新,我不得不使用一个处理程序和一个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 AppWidgetManager method updateAppWidget fails to set intents, load data. And it happens randomly

Android widget stops working after a while?

他们没有工作。如果你注意到,我每次调用更新函数时都会记录,其中调用AppWidgetManager来更新app小部件,所以我确信这一切都被调用了。在调用更新函数的意义上,小部件的远程视图不更新(如果不清楚)。任何关于小部件远程视图为什么会在一段时间(~5-10分钟)后停止更新的任何帮助都将非常感激。如果您需要更多信息,请告诉我们!

该项目也是开源的,因此您可以在此处查看所有代码:

https://github.com/torch2424/Stats-Monitor-Widget

谢谢!

0 个答案:

没有答案