Mein Widget ist ein leerer Hintergrund, der zwischen zwei Farben mit einer Verzögerung von 333ms zwischen jedem Schalter wechselt. Es funktioniert zunächst gut, aber nach 158 Schaltern hört es auf, Farben zu wechseln. Die Sache ist, ich verlasse mich nicht auf OnUpdate. Alles ist in einer unendlichen while-Schleife, die zuerst aufgerufen wird, wenn ich das Widget auf meinem Home-Bildschirm platziere. Was könnte dazu führen, dass es nach 158 Schaltern nicht mehr schaltet? Könnte das Ändern der Hintergrundfarbe zu teuer sein, und das OS deaktiviert mein Widget?Was funktioniert, wenn die Endlosschleife meines Widgets nicht mehr funktioniert?
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>
Das Widget funktioniert ... einfach nicht für sehr lang. Ist die Endlosschleife eine schlechte Wahl?
Bearbeiten: Es wurde eine Problemumgehung gefunden, die Thread.sleep() nicht verwendet. Ich bin mir nicht sicher, ob dies Probleme oder Speicherprobleme verursachen wird, aber es scheint für jetzt zu funktionieren.
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);
fand gerade erstrecken, wie schlecht es um Thread.sleep ist() hier ... Ich habe auch versucht Thread.sleep setzen (1000) es in einem eigenen Thread, aber es scheint nicht zu verzögern, den SetBackground-Code. Meine Vermutung ist, dass der andere Thread schlief, während der Haupt-Thread einfach weiterging. – Kawaii
Sekundäre Threads haben ihren eigenen Thread, also läuft der Haupt-Thread weiter. Das ist der Punkt. Blockiere den Hauptthread und deine App wird ANR bekommen und möglicherweise abstürzen. Schwere Operationen sollten immer an einem Thread ausgeführt werden, der nicht der Hauptthread ist – Zoe