0

을 AppWidgetProvider로 구현하고 싶습니다.Android 아키텍처 구성 요소가있는 AppWidgetProvider

정확하게 위젯 라이프 사이클을 LifeCycle events에 매핑 할 것인지 확실하지 않습니다.

나는 내 위젯에 의해 extented 할 수있는 BaseAppWidgetProvider을 만들어 :

/** 
* Base class for {@link BaseAppWidgetProvider} to manage {@link Lifecycle} 
*/ 

public abstract class BaseAppWidgetProvider extends AppWidgetProvider implements LifecycleOwner { 
    private final AppWidgetProviderLifecycleDispatcher mDispatcher = new AppWidgetProviderLifecycleDispatcher(this); 

    public BaseAppWidgetProvider(){ 
     mDispatcher.onConstructor(); 
    } 

    @CallSuper 
    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
     mDispatcher.onUpdate(); 
     super.onUpdate(context, appWidgetManager, appWidgetIds); 
    } 

    @CallSuper 
    @Override 
    public void onDeleted(Context context, int[] appWidgetIds) { 
     mDispatcher.onDeleted(); 
     super.onDeleted(context, appWidgetIds); 
    } 

    @CallSuper 
    @Override 
    public void onEnabled(Context context) { 
     mDispatcher.onEnabled(); 
     super.onEnabled(context); 
    } 

    @CallSuper 
    @Override 
    public void onDisabled(Context context) { 
     mDispatcher.onDisabled(); 
     super.onDisabled(context); 
    } 

    @CallSuper 
    @Override 
    public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) { 
     mDispatcher.onRestored(); 
     super.onRestored(context, oldWidgetIds, newWidgetIds); 
    } 

    @CallSuper 
    @Override 
    public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { 
     mDispatcher.onAppWidgetOptionsChanged(); 
     super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); 
    } 

    @NonNull 
    @Override 
    public Lifecycle getLifecycle() { 
     return mDispatcher.getLifecycle(); 
    } 
} 

그리고 디스패처

public class AppWidgetProviderLifecycleDispatcher { 
    private final LifecycleRegistry mRegistry; 
    private final Handler mHandler; 
    private DispatchRunnable mLastDispatchRunnable; 


    /** 
    * @param provider {@link LifecycleOwner} for a service, usually it is a service itself 
    */ 
    public AppWidgetProviderLifecycleDispatcher(@NonNull LifecycleOwner provider) { 
     mRegistry = new LifecycleRegistry(provider); 
     mHandler = new Handler(); 
    } 
    private void postDispatchRunnable(Lifecycle.Event event) { 
     Timber.d("postDispatchRunnable event="+event); 
     if (mLastDispatchRunnable != null) { 
      mLastDispatchRunnable.run(); 
     } 
     mLastDispatchRunnable = new DispatchRunnable(mRegistry, event); 
     mHandler.postAtFrontOfQueue(mLastDispatchRunnable); 
    } 


    /** 
    * Must be a first call in {@link android.appwidget.AppWidgetProvider#AppWidgetProvider()} constructor, even before super call. 
    */ 
    public void onConstructor(){ 
     postDispatchRunnable(Lifecycle.Event.ON_CREATE); 
     postDispatchRunnable(Lifecycle.Event.ON_START); 
    } 

    /** 
    * Must be a first call in {@link android.appwidget.AppWidgetProvider#onDeleted(Context, int[])} method, even before super.onDeleted call. 
    */ 
    public void onDeleted(){ 
     postDispatchRunnable(Lifecycle.Event.ON_PAUSE); 
     postDispatchRunnable(Lifecycle.Event.ON_STOP); 
     postDispatchRunnable(Lifecycle.Event.ON_DESTROY); 
    } 

    /** 
    * Must be a first call in {@link android.appwidget.AppWidgetProvider#onDisabled(Context)} method, even before super.onDisabled call. 
    */ 
    public void onDisabled(){ 
     postDispatchRunnable(Lifecycle.Event.ON_PAUSE); 
     postDispatchRunnable(Lifecycle.Event.ON_STOP); 
     postDispatchRunnable(Lifecycle.Event.ON_DESTROY); 
    } 

    /** 
    * Must be a first call in {@link android.appwidget.AppWidgetProvider#onEnabled(Context)} method, even before super.onEnabled call. 
    */ 
    public void onEnabled(){ 
     postDispatchRunnable(Lifecycle.Event.ON_CREATE); 
     postDispatchRunnable(Lifecycle.Event.ON_START); 
    } 


    /** 
    * Must be a first call in {@link android.appwidget.AppWidgetProvider#onRestored(Context, int[], int[])} method, even before super.onRestored call. 
    */ 
    public void onRestored(){ 
     postDispatchRunnable(Lifecycle.Event.ON_CREATE); 
     postDispatchRunnable(Lifecycle.Event.ON_START); 
    } 

    /** 
    * Must be a first call in {@link android.appwidget.AppWidgetProvider#onUpdate(Context, AppWidgetManager, int[])} method, even before super.onUpdate call. 
    */ 
    public void onUpdate(){ 
     postDispatchRunnable(Lifecycle.Event.ON_RESUME); 
    } 

    /** 
    * @return {@link Lifecycle} for the given {@link LifecycleOwner} 
    */ 
    public Lifecycle getLifecycle() { 
     return mRegistry; 
    } 

    public void onAppWidgetOptionsChanged() { 
     postDispatchRunnable(Lifecycle.Event.ON_RESUME); 
    } 

    static class DispatchRunnable implements Runnable { 
     private final LifecycleRegistry mRegistry; 
     final Lifecycle.Event mEvent; 
     private boolean mWasExecuted = false; 
     DispatchRunnable(@NonNull LifecycleRegistry registry, Lifecycle.Event event) { 
      mRegistry = registry; 
      mEvent = event; 
     } 
     @Override 
     public void run() { 
      if (!mWasExecuted) { 
       mRegistry.handleLifecycleEvent(mEvent); 
       mWasExecuted = true; 
      } 
     } 
    } 

} 

답변

2

AppWidgetProviderBroadcastReceiver이다. 수명주기가 없습니다. AppWidgetProvider의 인스턴스는 정확히 하나의 콜백 메소드 (예 : onUpdate()) 만 사용합니다. 따라서 Lifecycle 이벤트에 대한 매핑이 없으므로 Lifecycle 이벤트가 일반 BrodadcastReceiver에 매핑되어 있지 않은 것과 마찬가지입니다.

+0

답변 감사합니다. 위젯과 함께 LiveData를 사용할 수 있습니까? – LaurentY

+0

@LaurentY : 매니 페스트에 등록 된 'BroadcastReceiver'와 함께 'LiveData'를 사용할 수없는 것과 마찬가지입니다. 'LiveData'는 오래 지속되는 구성 요소를위한 것입니다 : 주로 활동과 서비스. – CommonsWare