내 응용 프로그램의 모든 활동을 보려면 사용자가 로그인해야합니다. 사용자는 거의 모든 활동에서 로그 아웃 할 수 있습니다. 이것은 응용 프로그램의 요구 사항입니다. 사용자가 로그 아웃하면 언제든지 사용자를 Login으로 보내려고합니다 Activity
. 이 시점에서이 활동이 히스토리 스택의 맨 아래에 있기를 원하므로 “뒤로”단추를 누르면 사용자가 Android 홈 화면으로 돌아갑니다.
나는이 질문이 몇 가지 다른 장소를 요구하는 것을 보았습니다. 모두 비슷한 대답으로 대답했습니다.
설명서에 설명 된 것처럼 Intent
플래그를 설정하여 로그인 활동을 열려고 FLAG_ACTIVITY_CLEAR_TOP
했지만 로그인 활동을 기록 스택의 맨 아래에 배치하고 사용자가 다시 탐색하지 못하게하는 목표를 달성하지 못했습니다. 이전에 본 로그인 활동 또한 android:launchMode="singleTop"
매니페스트에서 Login 활동에 사용해 보았지만 이것이 목표를 달성하지 못합니다 (어쨌든 효과가없는 것 같습니다).
나는 역사 스택을 지우거나 이전에 열었던 모든 활동을 끝내야한다고 생각합니다.
한 가지 옵션은 각 활동의 onCreate
확인 상태를 finish()
로그인하고 로그인하지 않은 경우입니다. 이 옵션이 마음에 들지 않습니다. 뒤로 버튼을 계속 사용할 수 있으므로 활동이 닫힐 때 뒤로 돌아갑니다.
다음 옵션은 LinkedList
모든 곳에서 정적으로 액세스 할 수있는 모든 열린 활동 (아마도 약한 참조를 사용)에 대한 참조 를 유지하는 것입니다. 로그 아웃하면이 목록에 액세스하여 이전에 열었던 모든 활동을 반복 finish()
하여 각 활동을 호출 합니다. 아마이 방법을 곧 구현하기 시작할 것입니다.
Intent
그러나 오히려 이것을 달성 하기 위해 깃발 속임수를 사용하고 싶습니다 . 위에서 설명한 두 가지 방법 중 하나를 사용하지 않고도 응용 프로그램 요구 사항을 충족시킬 수 있다는 사실을 알게되어 기쁩니다.
Intent
설정 또는 매니페스트 설정 을 사용하여이 작업을 수행 할 수있는 방법이 있습니까? 아니면 두 번째 옵션 LinkedList
인 열린 활동을 유지하는 것이 최선의 옵션입니까? 아니면 내가 완전히 간과하는 또 다른 옵션이 있습니까?
답변
IMHO가 더 강력한 다른 접근법을 제안 할 수 있습니다. 기본적으로 로그인 상태를 유지해야하는 모든 활동에 로그 아웃 메시지를 브로드 캐스트해야합니다. 그래서 당신은 모든 활동에를 사용 sendBroadcast
하고 설치할 수 있습니다 BroadcastReceiver
. 이 같은:
/** on your logout method:**/
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_LOGOUT");
sendBroadcast(broadcastIntent);
수신자 (보안 활동) :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**snip **/
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.package.ACTION_LOGOUT");
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("onReceive","Logout in progress");
//At this point you should start the login activity and finish this one
finish();
}
}, intentFilter);
//** snip **//
}
답변
새로운 안드로이드 프로그래머가이 문제를 연구하고이 모든 StackOverflow 스레드를 읽는 데 하루를 보내는 것은 통과의 의례처럼 보입니다. 나는 지금 새로 시작했고 나는 미래의 순례자를 돕기 위해 겸손한 경험의 흔적을 남깁니다.
첫째, 명백한 또는 즉시 내 연구에 따라이 작업을 수행하는 방법이 없습니다 (as of September 2012).
당신이 간단 할 수 생각하지 거라고 startActivity(new Intent(this, LoginActivity.class), CLEAR_STACK)
하지만 더 .
당신은 할 수 startActivity(new Intent(this, LoginActivity.class))
와 FLAG_ACTIVITY_CLEAR_TOP
– 이것은 스택을 검색 LoginActivity 당신의 이전 원본 인스턴스를 찾아 다시 작성하고 (위쪽으로) 스택의 나머지 부분을 취소 프레임 워크의 원인이됩니다. 로그인은 스택의 맨 아래에있을 것으로 예상되므로 이제 빈 스택이 있고 뒤로 버튼은 응용 프로그램을 종료합니다.
그러나 이것은 이전에 LoginActivity의 원래 인스턴스를 스택 기반에 남겨둔 경우에만 작동합니다. 많은 프로그래머처럼, 당신이 선택, 경우 finish()
그 LoginActivity
사용자가 성공적으로 다음 스택의 기초에 더 이상의와,에 기록되면 FLAG_ACTIVITY_CLEAR_TOP
의미가 적용되지 않습니다 … 새를 만들어 결국 LoginActivity
기존의 스택의 상단에. 거의 확실하게 원하는 것이 아닙니다 (사용자가 이전 화면에 로그인하지 못하게하는 이상한 행동).
이전 그래서 만약 finish()
‘는 d는 LoginActivity
당신이 당신의 스택을 삭제하고 새로운 시작을위한 몇 가지 메커니즘을 추구해야합니다 LoginActivity
. @doreamon
이 스레드에서 답변 이 가장 좋은 해결책 인 것 같습니다 (적어도 내 겸손한 눈에).
https://stackoverflow.com/a/9580057/614880
LoginActivity를 활성 상태로 두 었는지 여부에 대한 까다로운 영향으로 인해 많은 혼란이 초래 될 것입니다.
행운을 빕니다.
답변
최신 정보
슈퍼 finishAffinity()
메소드는 코드를 줄이는 데 도움이되지만 동일한 결과를 얻을 수 있습니다. 스택의 모든 활동뿐만 아니라 현재 활동을 완료합니다 getActivity().finishAffinity()
. 조각 상태 인 경우 사용 하십시오.
finishAffinity();
startActivity(new Intent(mActivity, LoginActivity.class));
원래 답변
LoginActivity-> HomeActivity-> …-> SettingsActivity 호출 signOut ()이라고 가정하십시오.
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();
}
이것은 나를 위해 작동합니다, 그것이 당신에게도 도움이되기를 바랍니다. 🙂
답변
API 11 이상을 사용하는 경우 다음을 시도해보십시오 FLAG_ACTIVITY_CLEAR_TASK
.-문제를 정확하게 해결하는 것 같습니다. 분명히 API 11 이전의 군중은 @doreamon이 제안했듯이 다른 모든 활동을 추가로 확인하는 조합을 사용해야합니다.
(또한 참고 : 이것을 사용하려면 전달해야합니다 FLAG_ACTIVITY_NEW_TASK
)
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();
답변
나는 이것에도 몇 시간을 보냈다 … 그리고 FLAG_ACTIVITY_CLEAR_TOP 은 당신이 원하는 것처럼 들린다 는 것에 동의합니다 : 시작되는 활동을 제외하고 전체 스택을 지우면 뒤로 버튼이 응용 프로그램을 종료합니다. 그러나 Mike Repass가 언급했듯이 FLAG_ACTIVITY_CLEAR_TOP은 실행중인 활동이 이미 스택에있는 경우에만 작동합니다. 활동이 없으면 플래그는 아무것도하지 않습니다.
무엇을해야합니까? 와 스택의 활동 존재 발사를 넣어 FLAG_ACTIVITY_NEW_TASK 그 활동을 역사의 스택에 새 작업의 시작을한다. 그런 다음 FLAG_ACTIVITY_CLEAR_TOP 플래그를 추가하십시오.
이제 FLAG_ACTIVITY_CLEAR_TOP이 스택에서 새로운 활동을 찾으면 모든 것이 지워지기 전에 거기에 있고 풀려납니다.
여기 내 로그 아웃 기능이 있습니다. View 매개 변수는 기능이 첨부 된 버튼입니다.
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 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()
답변
이것을 사용하면 도움이 될 것입니다. 약간 수정 된 xbakesx 답변.
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);