是什么让我的小部件的无限循环停止工作?

What is making my widget's infinite loop stop working?

我的小部件是一个空白背景,可以在两种颜色之间切换,每次切换之间有 333 毫秒的延迟。起初它工作正常,但在 158 次切换后,它停止切换颜色。问题是,我不依赖于 onUpdate。一切都在一个无限的 while 循环中,当我将小部件放在主屏幕上时,它首先被调用。是什么导致它在 158 次切换后停止切换?像这样更改背景颜色会不会成本太高,而且 OS 会禁用我的小部件?

ColorSwitchWidget.java:

public class ColorSwitchWidget extends AppWidgetProvider {

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {

        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.color_switch_widget);

        boolean lightOn = true;

        while(true){
            try{
                Thread.sleep(333);
            } catch(InterruptedException e){
            }

            if (lightOn) {
                views.setInt(R.id.RelativeLayout1, "setBackgroundColor", Color.argb(150, 255, 248, 231)); //color 1
                lightOn = false;
                appWidgetManager.updateAppWidget(appWidgetId, views);
            } else {
                views.setInt(R.id.RelativeLayout1, "setBackgroundColor", Color.argb(220, 255, 248, 231)); //color 2
                lightOn = true;
                appWidgetManager.updateAppWidget(appWidgetId, views);
            }
        }
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager, appWidgetManager, int[] appWidgetIds) {
        for (int appWidgetId : appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }

    @Override
    public void onEnabled(Context context) {
    }

    @Override
    public void onDisabled(Context context) {
    }
}

color_switch_widget_info.xml:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider 
xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialKeyguardLayout="@layout/color_switch_widget"
    android:initialLayout="@layout/color_switch_widget"
    android:minHeight="40dp"
    android:minWidth="40dp"
    android:previewImage="@drawable/widget_icon_blink"
    android:resizeMode="horizontal|vertical"
    android:updatePeriodMillis="1800000"
    android:widgetCategory="home_screen"></appwidget-provider>

小部件可以工作...只是不会持续很长时间。无限循环是一个糟糕的选择吗?

编辑:找到了不使用 Thread.sleep() 的解决方法。我不确定这是否会导致问题或内存问题,但它现在似乎有效。

final Handler myHandler = new Handler();
final Runnable blinkRunnable = new Runnable(){
    int lightOff = true;
    public void run(){
        if(lightOff){
            lightOff = false;
            views.setInt(R.id.RelativeLayout1, "setBackgroundColor", Color.argb(220, 255, 248, 231)); //light "on"
            appWidgetManager.updateAppWidget(appWidgetId, views);
            myHandler.postDelayed(this, 333);
        } else{
            lightOff = true;
            views.setInt(R.id.RelativeLayout1, "setBackgroundColor", Color.argb(150, 255, 248, 231)); //light "off"
            appWidgetManager.updateAppWidget(appWidgetId, views);
            myHandler.postDelayed(this, 333);
        }
    }
};

//start the loop
myHandler.post(blinkRunnable); 

这里的问题是您没有 运行 在自定义线程上。该方法是从主线程调用的,当您暂停主线程时(Thread.sleep()) Android 认为应用程序没有响应。

通过创建新的 class 并让它扩展 Thread

来代替使用新线程