Java AppWidgetManager在短时间后停止更新其RemoteView

Java AppWidgetManager在短时间后停止更新其RemoteView,java,android,widget,Java,Android,Widget,我目前正在更新我不久前制作的一个小部件,小部件视图冻结有问题,或者它在一段时间后停止更新 该应用程序是一个每秒更新一次的系统监视器(是的,我知道经常更新会影响电池寿命,但我设置了一些广播接收器来禁用更新,以显著帮助实现这一点),并且由于报警管理器不再允许每秒更新,我必须使用一个处理程序和一个runnable来调用一个对象,该对象接受上下文来更新我们的远程视图和小部件 它从提供程序创建和调用对象开始: ProviderHelper.java //Save our context c

我目前正在更新我不久前制作的一个小部件,小部件视图冻结有问题,或者它在一段时间后停止更新

该应用程序是一个每秒更新一次的系统监视器(是的,我知道经常更新会影响电池寿命,但我设置了一些广播接收器来禁用更新,以显著帮助实现这一点),并且由于报警管理器不再允许每秒更新,我必须使用一个处理程序和一个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);
    }
    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());
}
//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

//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);
    }
    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());
}
//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));
}
例如,下面是来自时间小部件帮助器的调用

TimeHelper.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);
    }
    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());
}
//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函数时,我都会记录日志,其中AppWidgetManager被调用以更新应用程序小部件,因此我确信这也会被调用。在调用更新函数的意义上,小部件的remoteview没有更新(如果不清楚的话)。如果您能提供有关小部件远程视图在一段时间(约5-10分钟)后停止更新的任何帮助,我们将不胜感激。如果你需要更多的信息,请告诉我

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

谢谢大家!