全履歴スタックをクリアし、Androidで新しいアクティビティを開始します
-
28-09-2019 - |
質問
スタックでアクティビティを開始し、その前に歴史全体をクリアすることは可能ですか?
状況
A-> b-> cまたはb-> cになるアクティビティスタックがあります(スクリーンAはユーザートークンを選択しますが、多くのユーザーは単一のトークンしか持っていません)。
画面cでユーザー 五月 画面Bを無効にするアクションを実行するため、アプリケーションは、既にスタックにあるかどうかに関係なく、それらを画面Aに引き継ぎたいと考えています。画面Aは、アプリケーションのスタック上の唯一のアイテムです。
ノート
他にも多くの同様の質問がありますが、この正確な質問に答えるものは何も見つかりませんでした。電話してみました getParent().finish()
- これにより、常にヌルポインターの例外が生じます。 FLAG_ACTIVITY_CLEAR_TOP
アクティビティがすでにスタック上にある場合にのみ機能します。
解決
APIレベル11では、これだけのために新しい意図フラグが追加されました。 Intent.flag_activity_clear_task
明確にするために、これを使用してください。
ジャワ
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
コトリン
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
残念ながら、API LVL <= 10では、これに対するきれいな解決策をまだ見つけていません。 「Donthackandroidlikethis」ソリューション 確かに純粋なハッカーです。あなたはそれをするべきではありません。 :)
編集:@に従ってベン・ピアソンのコメント、api <= 10のために今では使用できます IntentCompat 同じためのクラス。使用できます IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
タスクをクリアするフラグ。したがって、Pre APIレベル11もサポートできます。
他のヒント
ケース1:2つのアクティビティAとBのみ:
ここで、アクティビティフローはa-> b。bからバックボタンをクリックすると、アプリケーションを閉じる必要があります。その後、アクティビティBからアクティビティBを開始すると、AndroidはAndroidがアクティビティaをBackstack.egに保存できなくなります。アプリケーションの積み込み/スプラッシュ画面。
Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();
ケース2:2つ以上のアクティビティ:
A-> b-> c-> d-> bのようなフローがある場合、アクティビティBからのアクティビティBのバックボタンをクリックすると、その場合は使用する必要があります。
Intent newIntent = new Intent(D.this,B.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);
ここで、アクティビティBは、意図のために新しいインスタンスではなく、バックスタックから開始されます。flag_activity_clear_topとintent.flag_activity_new_taskはスタックをクリアし、最上位にします。
Androidの新しいバージョンで> = API 16使用 finishAffinity()
アプローチは> = API 16に適しています。
Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
- 新しいアクティビティを開始することと同じで、すべてのスタックをクリアします。
- または、MainActivity/FirstActivityに再起動します。
私もこれに数時間を費やしました...そして、flag_activity_clear_topはあなたが望むもののように聞こえることに同意します。しかし、Mike Repassが言及したように、flag_activity_clear_topは、起動しているアクティビティがすでにスタックにある場合にのみ機能します。アクティビティがそこにない場合、フラグは何もしません。
何をすべきか? flag_activity_new_taskを使用してスタックで起動するアクティビティを配置します。これにより、そのアクティビティは履歴スタックで新しいタスクの開始になります。次に、flag_activity_clear_topフラグを追加します。
これで、flag_activity_clear_topがスタック内の新しいアクティビティを見つけに行くと、他のすべてがクリアされる前にそこにあり、引き上げられます。
これが私のログアウト関数です。ビューパラメーターは、関数が添付されているボタンです。
public void onLogoutClick(final View view) {
Intent i = new Intent(this, Splash.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
finish();
}
スタックを変更しないでください。 Androidバックボタンは、Webブラウザのように機能するはずです。
私はそれをする方法を考えることができますが、それはかなりハックです。
あなたの活動をしてください
singleTask
に追加することによりAndroidManifest
例:<activity android:name=".activities.A" android:label="@string/A_title" android:launchMode="singleTask"/> <activity android:name=".activities.B" android:label="@string/B_title" android:launchMode="singleTask"/>
拡張する
Application
これは、どこへ行くべきかという論理を保持します。
例:
public class DontHackAndroidLikeThis extends Application {
private Stack<Activity> classes = new Stack<Activity>();
public Activity getBackActivity() {
return classes.pop();
}
public void addBackActivity(Activity activity) {
classes.push(activity);
}
}
AからBへ:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(A.class);
startActivity(this, B.class);
BからCへ:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(B.class);
startActivity(this, C.class);
Cで:
If ( shouldNotGoBackToB() ) {
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.pop();
}
バックボタンを処理します pop()
スタックから。
もう一度、あなたはこれをするべきではありません:)
新しいアクティビティを開始した直後、使用します startActivity
, 、必ず電話してください finish()
現在のアクティビティが新しいアクティビティの背後に積み重なっていないように。
これを試して:
Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();
Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
以下のコードを試してください、
Intent intent = new Intent(ManageProfileActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
Intent.FLAG_ACTIVITY_CLEAR_TASK|
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
私のため 無し 上記の方法の うまくいかない。
これを行うだけです 以前のすべてのアクティビティをクリアします:
finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)
私はあまりにも簡単なハックを見つけましたこれを行うだけで新しい要素を追加します AndroidManifest
なので:-
<activity android:name=".activityName"
android:label="@string/app_name"
android:noHistory="true"/>
android:noHistory
スタックから不要なアクティビティをクリアします。
AndroidエミュレーターがEclipse DDMSツールを接続していない場合があり、ADBが手動で開始するように要求する場合があります。その場合、コマンドプロンプトを使用してADBを起動または停止できます。