首先,我知道在Android上不应该真正地关闭/重启应用程序。在我的用例中,我想在服务器向客户机发送一条特定信息的特定情况下对应用程序进行工厂重置。
用户只能使用应用程序的一个实例在服务器上登录(即不允许多个设备)。如果另一个实例得到了“login -in -lock”,那么该用户的所有其他实例都必须删除他们的数据(factory-reset),以保持一致性。
强制获取锁是可能的,因为用户可能会删除应用程序并重新安装它,这将导致不同的实例id,用户将无法再释放锁。因此,可以强制获取锁。
由于这种强制的可能性,我们需要始终检查一个具体实例是否拥有锁。这是在(几乎)对服务器的每个请求上完成的。服务器可能会发送一个“error -lock-id”。如果检测到这种情况,客户机应用程序必须删除所有内容。
这就是用例。
我有一个Activity
A,它开始登录Activity
L或应用程序的主Activity
B,这取决于一个sharedPrefs值。在启动L或B之后,它关闭自己,以便只有L或B在运行。在用户已经登录的情况下,B正在运行。
C为IntentService
d调用startService
,结果是这样的堆栈:
(一)比;B在C比;D
从D的onHandleIntent方法,一个事件被发送到ResultReceiver R。
R现在通过向用户提供一个对话框来处理该事件,在该对话框中,用户可以选择对应用程序进行工厂重置(删除数据库、sharedPrefs等)。
在工厂重置后,我想重新启动应用程序(关闭所有活动),只再次启动A,然后启动登录Activity
L并完成自己:
(一)比;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 ?