2017-09-12 6 views
0

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); 

Antwort

0

Das Problem hierbei ist die Tatsache, dass Sie es auf einem benutzerdefinierten Thread nicht ausgeführt. Die Methode wird vom Hauptthread aufgerufen, und wenn Sie den Hauptthread pausieren (Thread.sleep()), denkt Android, dass die Anwendung nicht reagiert.

einen neuen Thread Verwenden Sie stattdessen durch Erstellen einer neuen Klasse und lässt sie Thema

+0

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

+0

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

Verwandte Themen