What is the correct way to share data between AppWidgetProvider and RemoteViewsService.RemoteViewsFactory

Mine currently AppWidgetProviderhas static data. It is used for information passing around AppWidgetProviderandRemoteViewsService.RemoteViewsFactory

public class MyAppWidgetProvider extends AppWidgetProvider {
    // Key will be widget id
    private static Map<Integer, Holder> holderMap = new java.util.concurrent.ConcurrentHashMap<Integer, Holder>();

    public static int getClickedColumn(int appWidgetId) {
        Holder holder = holderMap.get(appWidgetId);  
        if (holder == null) {
            return -1;
        }
        return holder.clickedColumn;
    }

public class AppWidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
    @Override
    public void onDataSetChanged() {
        int clickedColumn = MyAppWidgetProvider.getClickedColumn(mAppWidgetId);

Calling a AppWidgetProviderstatic method works fine in most situations.

However, sometimes, if I put the widget on the main screen, let it be there for several hours. When I get back and mow ListView, I might accidentally get the following error.

java.lang.ExceptionInInitializerError
    at org.yccheok.project.gui.widget.AppWidgetRemoteViewsFactory.onDataSetChanged(AppWidgetRemoteViewsService.java:390)
    at android.widget.RemoteViewsService$RemoteViewsFactoryAdapter.onDataSetChanged(RemoteViewsService.java:142)
    at com.android.internal.widget.IRemoteViewsFactory$Stub.onTransact(IRemoteViewsFactory.java:49)
    at android.os.Binder.execTransact(Binder.java:367)
    at dalvik.system.NativeStart.run(Native Method)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:121)
    at org.yccheok.project.gui.widget.MyAppWidgetProvider.<clinit>(MyAppWidgetProvider.java:564)

Of <clinit>, I suspect that MyAppWidgetProviderthe OS is destroyed? Does this reason AppWidgetRemoteViewsFactorywant to initialize the class before calling a static function?

, MyAppWidgetProvider , ?

, AppWidgetProvider RemoteViewsService.RemoteViewsFactory? ( SharedPreferences)

+4
1

RemoteViewsFactory → AppWidgetProvider

RemoteViewsFactory AppWidgetProvider , . :

Intent intent = new Intent(ACTION_PROGRESS_OFF);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);

AppWidgetProvider :

@Override
public void onReceive(final Context context, final Intent intent) {

    // here goes the check if the app widget id is ours

    final String action = intent.getAction();
    if (ACTION_PROGRESS_OFF.equals(action)) {
        // turn off the refresh spinner

, :

<receiver
    android:name="...">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        <action android:name="myPackage.ACTION_PROGRESS_OFF" />
    </intent-filter>
    <meta-data ... />
</receiver>

AppWidgetProvider → RemoteViewsFactory

RemoteViewsFactory (, , , ) - , RemoteViewsAdapter:

Intent intentRVService = new Intent(context, RemoteViewsService.class);
intentRVService.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

// let put in some extra information we want to pass to the RemoteViewsFactory
intentRVService.putExtra("HELLO", "WORLD");

// when intents are compared, the extras are ignored, so we need to
// embed the extras into the data so that the extras will not be ignored
intentRVService.setData(Uri.parse(intentRVService.toUri(Intent.URI_INTENT_SCHEME)));

rv.setRemoteAdapter(appWidgetId, R.id.my_list, intentRVService);
rv.setEmptyView(R.id.my_list, android.R.id.empty);

// create the pending intent template for individual list items
...
rv.setPendingIntentTemplate(R.id.my_list, pendingIntentTemplate);

appWidgetMgr.notifyAppWidgetViewDataChanged(appWidgetId, R.id.my_list);

RemoteViewsService RemoteViewsService.RemoteViewsFactory.

100%, , , , notifyAppWidgetViewDataChanged, . , - (SharedPreferences).

+10

Source: https://habr.com/ru/post/1532861/


All Articles