应用程序被强制停止后,小部件无法正常启动

Wil*_*ani 5 java android widget

我有一个小部件,它根据按下的各种小部件按钮启动到特定页面。当我在内存中使用应用程序时它工作正常(即从部署(运行/调试)开始,但是当我强制停止应用程序时,小部件不再正常工作。

当应用程序被强制停止时,小部件的第一次点击正常工作,并调用相应 Activity 的 onCreate。然后,当按下home键,按下不同的widget按钮时,会调用之前的widgetActivity的onRestart方法。

奇怪的是,b/c 日志消息没有出现,并且由于无法连接调试器,因此测试起来相当困难。有什么特别我做错的吗?

流程是 --> WidgetDispatchActivity (handle true widget destination) --> ViewActivity > -->进一步分支(DetailViewActivity在下面的例子中)

onUpdate 对于小部件:

onUpdate(){
...


       Intent viewIntent = new Intent(context, WidgetDispatchActivity.class);
                    viewIntent.putExtra("launch", WidgetInfo.VIEW_ACTIVITY);
                    PendingIntent viewPendIntent = PendingIntent.getActivity(context, 2, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT);

...
}
Run Code Online (Sandbox Code Playgroud)

WidgetDispatchActivity 的onCreate

 Bundle b = getIntent().getExtras();
        if (b != null && b.isEmpty()){
            Log.i(LOG_TAG, "EMPTY BUNDLE ON WIDGET!");
        }else{
            Log.i(LOG_TAG, "WIDGET BUNDLE HAS ITEMS!");
        }

        String destination = null;
        if (b != null && b.containsKey("launch")){
            destination = b.getString("launch");
            Log.i(LOG_TAG, "WIDGET ITEM FROM BUNDLE WAS: " + destination);
        }
        else{
            Log.i(LOG_TAG, " \"launch\" item was not inside bundle!");
        }

        if(destination != null) {
            Log.i(LOG_TAG, "PendingIntent received from widget!");
            Intent goTo = new Intent(this, ViewActivity.class);
               ...
}
}
Run Code Online (Sandbox Code Playgroud)

日志猫

10-10 20:38:00.935: INFO/ActivityManager(58): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.android.launcher/com.android.launcher2.Launcher }
10-10 20:38:00.956: INFO/DetailViewActivity(1154): ONPAUSE
10-10 20:38:00.975: WARN/InputManagerService(58): Ignoring hideSoftInput of: com.android.internal.view.IInputMethodClient$Stub$Proxy@450366d0
10-10 20:38:02.545: INFO/ActivityManager(58): Starting activity: Intent { flg=0x10000000 cmp=com.starbucks.mobilecard/com.xxx.xxx.widget.WidgetDispatchActivity bnds=[198,298][224,321] (has extras) }
10-10 20:38:02.585: INFO/ViewActivity(1154): ONRESTART
10-10 20:38:02.585: INFO/ViewActivity(1154): WIDGET LAUNCH:: == false
Run Code Online (Sandbox Code Playgroud)

ViewActivity onRestart:

protected void onRestart(){
        super.onRestart();
        Log.i(LOG_TAG,"ONRESTART");

        Log.i(LOG_TAG,"WIDGET LAUNCH:: == " + WidgetInfo.getInstance().wasLaunchedFromWidget());
                 ...
}
Run Code Online (Sandbox Code Playgroud)

安卓清单:

<activity android:name="com.xxx.xxx.ui.cards.ViewActivity" android:label="@string/_view_title" android:finishOnTaskLaunch="true" android:clearTaskOnLaunch="true" android:screenOrientation="portrait"/>

<activity android:name="com.xxx.xxx.widget.WidgetDispatchActivity" android:label="@string/widget_dispatch_title" android:finishOnTaskLaunch="true"/>
Run Code Online (Sandbox Code Playgroud)

Fuz*_*gic 1

威尔梅尔,

强制关闭时停止小部件工作的第一步是实现 onDestroy()。在这里,您需要确保与构成 Widget 通信的 WidgetHost、HostView 和 RemoteView 进行通信。

此语句阻止 WidgetHost 接收来自 Android 的任何事件。myHost是对象,通常是保存对 Widget 引用的 Activity。

// Stop the Widgets from fidgeting
    myHost.stopListening();
    myHost = null;
Run Code Online (Sandbox Code Playgroud)

从那里,您将需要删除对您可能引用的任何 HostView 的任何引用。只需获取引用并将其设置为 即可完成此操作null。在我的例子中onDestroy(),我使用以下循环...

if (appWidgets != null) {
    final int count = appWidgets.size();
    for (int i = 0; i < count; i++) {
        final Widget launcherInfo = appWidgets.get(i);
        launcherInfo.hostView = null;
    }
}
Run Code Online (Sandbox Code Playgroud)

这里launcherInfo是我的扩展 AppWidget 对象。hostView指的是我的AppWidgetHostView(这是代表我的Widget的视图)。该appWidgets数组是我的启动器正在跟踪的小部件列表。总的来说非常简单。

使用 Widget 和 WidgetHost 可能会出现问题,具体取决于您的设置。上面的说法用在了正确的地方,确实有助于减轻痛苦。

模糊逻辑