首先,我知道不应真正终止/重启Android上的应用程序。在我的用例中,我想在服务器将特定信息发送到客户端的特定情况下,将应用程序恢复出厂设置。
用户只能使用一个应用程序实例登录到服务器上(即,不允许使用多个设备)。如果另一个实例获得了“登录”锁定,则该用户的所有其他实例都必须删除其数据(恢复出厂设置),以保持一致性。
可能会强行获得该锁,因为用户可能会删除该应用程序并重新安装它,这将导致生成不同的实例ID,并且用户将无法再释放该锁。因此可以强行获得锁。
由于这种可能性,我们需要始终在具体实例中检查它是否具有锁。这几乎是在对服务器的每个请求上完成的。服务器可能会发送“错误的锁ID”。如果检测到该错误,则客户端应用程序必须删除所有内容。
那是用例。
我有一个Activity
A,它根据sharedPrefs值启动登录Activity
L或应用程序的主Activity
B。启动L或B后,它会自行关闭,因此只有L或B在运行。因此,在用户已登录的情况下,B现在正在运行。
B开始。C呼吁startService
为IntentService
D.导致这个堆栈:
(A)> B> C> D
从D的onHandleIntent方法将事件发送到ResultReceiverR。
R现在通过为用户提供一个对话框来处理该事件,他可以在其中选择将工厂重置为应用程序(删除数据库,sharedPrefs等)。
恢复出厂设置后,我想重新启动应用程序(以关闭所有活动),仅再次启动A,然后启动登录Activity
L并完成自身:
(A)> L
对话框的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?