Mon widget est un fond blanc qui permute entre deux couleurs avec un délai de 333 ms entre chaque commutateur. Il fonctionne bien au début, mais après 158 commutateurs, il arrête de changer de couleur. La chose est, je ne compte pas sur onUpdate. Tout est dans une boucle while infinie qui est d'abord appelée lorsque je mets le widget sur mon écran d'accueil. Qu'est-ce qui pourrait l'amener à arrêter la commutation après 158 commutateurs? Est-ce que la modification de la couleur de fond comme celle-ci pourrait être trop coûteuse, et le système d'exploitation désactive mon widget?Qu'est-ce qui fait que la boucle infinie de mon widget ne fonctionne plus?
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>
Le widget fonctionne ... mais pas pour très longtemps. La boucle infinie est-elle un mauvais choix?
Modifier: une solution de contournement qui n'utilise pas Thread.sleep() a été trouvée. Je ne suis pas sûr si cela va causer des problèmes ou des problèmes de mémoire, mais cela semble fonctionner pour l'instant.
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);
viens de découvrir à quel point il est à Thread.sleep() ici ... J'ai aussi essayé de mettre Thread.sleep (1000) dans son propre thread, mais il ne semble pas retarder le code setBackground. Ma conjecture est que l'autre thread a dormi pendant que le fil principal continuait à avancer. – Kawaii
Les threads secondaires exécutent leur propre thread, donc bien sûr, le thread principal continue à fonctionner. C'est le but. Bloquez le thread principal et votre application recevra ANR et risque de tomber en panne. Les opérations lourdes doivent toujours être effectuées sur un thread qui n'est pas le thread principal – Zoe