应用程序被强制停止后,Widget 无法正常启动
我有一个小部件,它根据按下的各种小部件按钮启动到特定页面。当我将应用程序放在内存中时(即从部署(运行/调试)),它工作正常,但是当我强制停止应用程序时,小部件不再正常工作。
当应用程序被强制停止时,第一次单击小部件正常工作,并且调用相应 Activity 的 onCreate 然后,当按下 home 键并按下不同的小部件按钮时,会调用前一个小部件 Activity 的 onRestart 方法,
这是奇怪的,因为日志。消息不会出现,并且由于调试器无法连接,测试起来有什么特别的问题吗?
WidgetDispatchActivity(处理真正的小部件目标)ViewActivity em>> --> 进一步的分支(下面的例子中的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);
...
}
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);
...
}
}
LogCat
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
ViewActivity onRestart:
protected void onRestart(){
super.onRestart();
Log.i(LOG_TAG,"ONRESTART");
Log.i(LOG_TAG,"WIDGET LAUNCH:: == " + WidgetInfo.getInstance().wasLaunchedFromWidget());
...
}
AndroidManifest:
<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"/>
I have a widget which launches to a particular page based on the various widget buttons pressed. It works fine when I have the app in-memory (i.e. from deploy (run / debug), however when I force stop the app, the widget no longer functions properly.
When the app has been force stopped, the first click of the widget works properly, and the onCreate for the corresponding Activity is called. Then, when the home key is pressed, and a different widget button is pressed, the onRestart method of the previous widget Activity is called.
It is odd, b/c the log messages do not appear, and since the debugger cannot be connected, it's been rather difficult to test. Is there anything in particular that I'm doing wrong?
The flow is --> WidgetDispatchActivity (handle true widget destination) --> ViewActivity> --> further branch (DetailViewActivity
in below example)
onUpdate
for widget:
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);
...
}
WidgetDispatchActivity's 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);
...
}
}
LogCat
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
ViewActivity onRestart:
protected void onRestart(){
super.onRestart();
Log.i(LOG_TAG,"ONRESTART");
Log.i(LOG_TAG,"WIDGET LAUNCH:: == " + WidgetInfo.getInstance().wasLaunchedFromWidget());
...
}
AndroidManifest:
<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"/>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Willmel,
强制关闭时停止小部件工作的第一步是实现 onDestroy()。在这里,您需要确保与构成 Widget 通信的 WidgetHost、HostView 和 RemoteView 进行通信。
此语句阻止 WidgetHost 接收来自 Android 的任何事件。
myHost
是对象,通常是一个保存对您的 Widget 引用的 Activity。从那里,您将需要删除对您可能引用的任何 HostView 的任何引用。只需获取引用并将其设置为
null
即可完成此操作。在我的onDestroy()
中,我使用以下循环...在这里,
launcherInfo
是我的扩展 AppWidget 对象。hostView
指的是我的AppWidgetHostView(它是代表我的Widget 的视图)。appWidgets
数组是我的启动器正在跟踪的小部件列表。总的来说非常简单。使用 Widget 和 WidgetHost 可能会出现问题,具体取决于您的设置。上述说法在正确的地方确实有助于减轻痛苦。
模糊逻辑
Willmel,
The first step in stopping your widgets from working when you Force Close is implementing your onDestroy(). Here you will want to make sure you talk to your WidgetHost, the HostViews and the RemoteViews that make up your Widget communications.
This statement stops the WidgetHost from receiving any events from Android.
myHost
is the object, often an Activity that is holding the references to your Widget.From there, you'll want to remove any reference to any of the HostViews you might have a reference to. This is done by simply grabbing the reference and setting it to
null
. In myonDestroy()
I use the following loop...In here,
launcherInfo
is my extended AppWidget object.hostView
refers to my AppWidgetHostView (which is the view that represents my Widget). TheappWidgets
array is my list of Widgets that my launcher is tracking. Pretty simple over all.Working with Widgets and WidgetHosts can be problematic, depending on your set up. The above statements in the right place really help to ease the suffering.
FuzzicalLogic