是什么让我的小部件的无限循环停止工作?
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
来代替使用新线程
我的小部件是一个空白背景,可以在两种颜色之间切换,每次切换之间有 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
来代替使用新线程