まず、Androidでアプリケーションを強制終了/再起動してはいけないことを知っています。私の使用例では、サーバーが特定の情報をクライアントに送信する特定のケースでアプリケーションを出荷時設定にリセットしたいと思います。
ユーザーは、アプリケーションの1つのインスタンスを使用してサーバーにログインすることしかできません(つまり、複数のデバイスは許可されません)。別のインスタンスがその「ログイン済み」ロックを取得した場合、そのユーザーの他のすべてのインスタンスは、一貫性を維持するためにデータを削除(ファクトリーリセット)する必要があります。
ユーザーがアプリを削除して再インストールすると、異なるインスタンスIDが生成され、ユーザーがロックを解放できなくなるため、強制的にロックを取得することが可能です。そのため、強制的にロックを取得することが可能です。
その力の可能性のために、私たちは常に具体的なインスタンスでそれがロックを持っていることをチェックする必要があります。これは、サーバーへの(ほぼ)各要求に対して行われます。サーバーは「間違ったロックID」を送信する可能性があります。それが検出された場合、クライアントアプリケーションはすべてを削除する必要があります。
それがユースケースでした。
sharedPrefsの値に応じてActivity
、Login Activity
LまたはアプリのメインActivity
B を開始するAがあります。LまたはBを開始した後、LまたはBのみが実行されるように自身を閉じます。したがって、ユーザーがすでにログインしている場合、Bは現在実行中です。
BがCを開始します。C startService
がIntentService
Dを呼び出します。その結果、次のスタックになります。
(A)> B> C> D
DのonHandleIntentメソッドから、イベントがResultReceiver Rに送信されます。
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?
Dはによって開始されたバックグラウンドタスクからも呼び出される可能性があるContext
ため、アクティビティを使用できません。ServiceIntent
AlarmManager
では、これをアクティビティスタックが(A)> Lになるように解決するにはどうすればよいですか?