Android 注销时,清除活动历史堆栈,防止;“后退”;打开“仅登录”活动的按钮
我的应用程序中的所有活动都需要用户登录才能查看。用户几乎可以从任何活动中注销。这是应用程序的一个要求。在任何时候,如果用户注销,我都希望将用户发送到登录Android 注销时,清除活动历史堆栈,防止;“后退”;打开“仅登录”活动的按钮,android,android-lifecycle,activity-lifecycle,Android,Android Lifecycle,Activity Lifecycle,我的应用程序中的所有活动都需要用户登录才能查看。用户几乎可以从任何活动中注销。这是应用程序的一个要求。在任何时候,如果用户注销,我都希望将用户发送到登录活动。此时,我希望此活动位于历史堆栈的底部,以便按下“后退”按钮将用户返回到Android的主屏幕 我看到这个问题问了几个不同的地方,所有的答案都是相似的(我在这里概述),但我想在这里提出它来收集反馈 我尝试通过将登录活动的Intent标志设置为FLAG\u activity\u CLEAR\u TOP来打开登录活动,这似乎与文档中概述的一样,但
活动
。此时,我希望此活动位于历史堆栈的底部,以便按下“后退”按钮将用户返回到Android的主屏幕
我看到这个问题问了几个不同的地方,所有的答案都是相似的(我在这里概述),但我想在这里提出它来收集反馈
我尝试通过将登录活动的Intent
标志设置为FLAG\u activity\u CLEAR\u TOP
来打开登录活动,这似乎与文档中概述的一样,但没有实现将登录活动放在历史堆栈底部的目标,以及防止用户导航回以前看到的登录活动。我还尝试在清单中为登录活动使用android:launchMode=“singleTop”
,但这也没有达到我的目标(而且似乎没有任何效果)
我相信我需要清除历史堆栈,或者完成所有以前打开的活动
一个选项是让每个活动的onCreate
检查登录状态,如果未登录,则检查finish()。我不喜欢这个选项,因为“后退”按钮仍然可以使用,在活动自行关闭时导航回去
下一个选项是维护对所有打开活动的引用的LinkedList
,这些活动可以从任何地方静态访问(可能使用弱引用)。注销时,我将访问此列表并迭代所有以前打开的活动,对每个活动调用finish()
。我可能很快就会开始实现这个方法
然而,我宁愿使用一些意图
标记技巧来实现这一点。我会非常高兴地发现,我可以满足我的应用程序的要求,而不必使用上述两种方法中的任何一种
有没有办法通过使用Intent
或清单设置来实现这一点,或者我的第二个选项,维护已打开活动的LinkedList
是最佳选项?还是我完全忽略了另一个选择
一个选项是让每个活动的onCreate检查登录状态,如果未登录,则返回finish()。我不喜欢这个选项,因为“后退”按钮仍然可以使用,在活动自行关闭时导航回去
您要做的是在onStop()或onPause()方法上调用logout()和finish()。这将迫使Android在活动重新启动时调用onCreate(),因为它将不再在其活动堆栈中。然后按照您所说的做,在onCreate()中检查登录状态,如果未登录,则转发到登录屏幕
您可以做的另一件事是在onResume()中检查登录状态,如果未登录,请完成()并启动登录活动。我可以建议您另一种更可靠的方法。
基本上,您需要向所有需要保持登录状态的活动广播注销消息。因此,您可以在所有活动中使用sendBroadcast
并安装BroadcastReceiver
。
大概是这样的:
/** on your logout method:**/
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_LOGOUT");
sendBroadcast(broadcastIntent);
接收方(担保活动):
使用StartActivityForResult开始活动,注销时设置结果,并根据结果完成活动
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivityForResult(intent, BACK_SCREEN);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case BACK_SCREEN:
if (resultCode == REFRESH) {
setResult(REFRESH);
finish();
}
break;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog alertDialog = builder.create();
alertDialog
.setTitle((String) getResources().getText(R.string.home));
alertDialog.setMessage((String) getResources().getText(
R.string.gotoHome));
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
setResult(REFRESH);
finish();
}
});
alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
}
});
alertDialog.show();
return true;
} else
return super.onKeyDown(keyCode, event);
}
单击注销后,您可以将其称为
private void GoToPreviousActivity() {
setResult(REQUEST_CODE_LOGOUT);
this.finish();
}
上一个活动的onActivityResult()再次调用上述代码,直到完成所有活动。更新
superfinishafinity()
方法将有助于减少代码,但实现相同的效果。它将完成当前活动以及堆栈中的所有活动,如果在片段中,请使用getActivity().finishafinity()
finishAffinity();
startActivity(new Intent(mActivity, LoginActivity.class));
原始答案
假设LoginActivity-->HomeActivity-->…-->SettingsActivity调用注销():
家庭活动:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean finish = getIntent().getBooleanExtra("finish", false);
if (finish) {
startActivity(new Intent(mContext, LoginActivity.class));
finish();
return;
}
initializeView();
}
这对我很有用,希望对你也有帮助。:) 一位新的安卓程序员花一天时间研究这个问题,阅读所有这些StackOverflow线程,这似乎是一种仪式。我现在是新入行的,我在这里留下我卑微的经历的痕迹,以帮助未来的朝圣者
首先,根据我的研究(截至2012年9月),没有明显或直接的方法可以做到这一点。
你可能认为你可以简单地开始操作(新意图(这个,LoginActivity.class),清除\u堆栈)
但是没有
您可以使用FLAG\u ACTIVITY\u CLEAR\u TOP
执行startActivity(new Intent(this,LoginActivity.class))
,这将导致框架向下搜索堆栈,找到LoginActivity的早期原始实例,重新创建它并清除(向上)堆栈的其余部分。由于Login可能位于堆栈的底部,所以现在有一个空堆栈,而Back按钮只是退出应用程序
但是-只有当您之前将LoginActivity的原始实例保留在堆栈的底部时,这才有效。如果像许多程序员一样,一旦用户成功登录,您选择finish()
即LoginActivity
,那么它就不再位于堆栈的基础上,并且标志\u活动\u清除\u顶部语义不适用。。。您最终将在现有堆栈的顶部创建一个新的LoginActivity
。这几乎肯定不是你想要的(奇怪的行为,用户可以“返回”登录到上一个屏幕)
因此,如果您以前有finish()
'dLoginActivity
,则需要采用某种机制来清除堆栈,然后
void signOut() {
Intent intent = new Intent(this, HomeActivity.class);
intent.putExtra("finish", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // To clean up all activities
startActivity(intent);
finish();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean finish = getIntent().getBooleanExtra("finish", false);
if (finish) {
startActivity(new Intent(mContext, LoginActivity.class));
finish();
return;
}
initializeView();
}
Intent intent = new Intent(this, LoginActivity.class);
intent.putExtra("finish", true); // if you are checking for this in your other Activities
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_CLEAR_TASK |
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
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();
}
Intent i = new Intent(this, MainActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
startActivity(i);
finish();
} else {
startActivityForResult(i, REQUEST_LOGIN_GINGERBREAD);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB &&
requestCode == REQUEST_LOGIN_GINGERBREAD &&
resultCode == Activity.RESULT_CANCELED) {
moveTaskToBack(true);
}
Intent i = new Intent(this, LoginActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
Intent intent = new Intent(this, LoginActivity.class);
if(Build.VERSION.SDK_INT >= 11) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
} else {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
startActivity(intent);
Intent i = new Intent(SettingsActivity.this, LoginActivity.class);
i.addFlags(IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
// After logout redirect user to Loing Activity
Intent i = new Intent(_context, MainActivity.class);
// Closing all the Activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Add new Flag to start new Activity
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Staring Login Activity
_context.startActivity(i);
protected void onResume() {
super.onResume();
if (isAuthRequired()) {
checkAuthStatus();
}
}
private void checkAuthStatus() {
//check your shared pref value for login in this method
if (checkIfSharedPrefLoginValueIsTrue()) {
finish();
}
}
boolean isAuthRequired() {
return true;
}
Intent intent = new Intent(activity, SignInActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);
this.finish();
Intent(this, SignInActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}.also { startActivity(it) }
finish()
@Override
public void onBackPressed() {
// disable going back to the MainActivity
moveTaskToBack(true);
}
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();