首先,我知道不应该真正杀死/重新启动 Android 上的应用程序。在我的用例中,我想在服务器向客户端发送一条特定信息的特定情况下将我的应用程序恢复出厂设置。
用户只能使用应用程序的一个实例登录服务器(即不允许使用多个设备)。如果另一个实例获得了“登录”锁定,那么该用户的所有其他实例都必须删除他们的数据(恢复出厂设置),以保持一致性。
强制获取锁是可能的,因为用户可能会删除应用程序并重新安装它,这将导致不同的 instance-id 并且用户将无法再释放锁。因此可以强制获取锁。
由于这种强制的可能性,我们需要始终检查一个具体的实例,它有锁。这是在(几乎)对服务器的每个请求上完成的。服务器可能会发送“错误锁定 ID”。如果检测到这种情况,客户端应用程序必须删除所有内容。
那是用例。
我有一个 Activity
A 启动登录 Activity
L 或应用程序的主 Activity
B 取决于 sharedPrefs 值。在启动 L 或 B 后,它会自行关闭,以便只有 L 或 B 正在运行。因此,在用户已登录的情况下,B 现在正在运行。
B 启动 C。C 为 IntentService
D 调用 startService
—。这导致了这个堆栈:
(A) > B > C > D
从 D 的 onHandleIntent 方法,一个事件被发送到一个 ResultReceiver R。
R 现在通过向用户提供一个对话框来处理该事件,用户可以在该对话框中选择将应用程序恢复出厂设置(删除数据库、sharedPrefs 等)
恢复出厂设置后,我想重新启动应用程序(关闭所有活动),然后再次启动 A,然后启动登录 Activity
L 并自行完成:
(A) > L
Dialog 的 onClick 方法如下所示:
@Override
public void onClick(DialogInterface dialog, int which) {
// Will call onCancelListener
MyApplication.factoryReset(); // (Deletes the database, clears sharedPrefs, etc.)
Intent i = new Intent(MyApp.getContext(), A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MyApp.getContext().startActivity(i);
}
这就是 MyApp
类:
public class MyApp extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
public static Context getContext() {
return context;
}
public static void factoryReset() {
// ...
}
}
问题是如果我使用 FLAG_ACTIVITY_NEW_TASK
活动 B 和 C 仍在运行。如果我在登录时点击后退按钮 Activity
我看到 C,但我想返回主屏幕。
如果我没有设置 FLAG_ACTIVITY_NEW_TASK
我得到错误:
07-07 12:27:12.272: ERROR/AndroidRuntime(9512): android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
我不能使用活动的 Context
,因为 ServiceIntent
D 也可能从由 AlarmManager
启动的后台任务中调用。
那么我该如何解决这个活动堆栈变成(A)> L?
原文由 Stuck 发布,翻译遵循 CC BY-SA 4.0 许可协议
我得到了这个方法。