2017-09-12 17 views
0

My widget은 각 스위치 사이에 333ms의 지연 시간으로 두 가지 색상을 전환하는 빈 배경입니다. 그것은 처음에 잘 작동하지만, 158 스위치 후, 그것은 색상을 전환 중지합니다. 문제는 onUpdate에 의지하지 않는다는 것입니다. 모든 것은 홈 화면에 위젯을 넣을 때 처음 호출되는 무한 while 루프에 있습니다. 158 스위치 후에 스위치가 멈추는 원인은 무엇입니까? 이렇게 배경 색상을 변경하면 비용이 너무 많이 들며 운영체제가 내 위젯을 사용하지 못하게 할 수 있습니까?내 위젯의 무한 루프가 작동하지 않게 만드는 이유는 무엇입니까?

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

답변

0

여기의 문제는 사용자 지정 스레드에서 실행하지 않는다는 것입니다. 이 메서드는 주 스레드에서 호출되며 주 스레드 (Thread.sleep())를 일시 중지하면 Android에서 응용 프로그램이 응답하지 않는다고 생각합니다.

대신 새로운 클래스를 생성하고 스레드 확장 시켜서 새 스레드를 사용

+0

그냥 (1000)는 여기)에 Thread.sleep (에 얼마나 나쁜에 대해 ... 나는 또한에 Thread.sleep 퍼팅 시도 발견 그것은 자체 스레드에서하지만 setBackground 코드를 지연시키지 않는 것 같습니다. 내 생각에 메인 스레드가 계속 진행되는 동안 다른 스레드는 잠자기 상태입니다. – Kawaii

+0

보조 스레드는 자체 스레드를 실행하므로 주 스레드는 계속 실행됩니다. 그게 핵심이야. 주요 스레드를 블로킹하면 앱에 ANR이 발생하고 충돌 할 수 있습니다. 무거운 작업은 항상 주 스레드가 아닌 스레드에서 수행되어야합니다. – Zoe