로그아웃 시 활동 기록 스택을 삭제하여 "뒤로" 단추가 로그인한 활동만 열 수 없도록 합니다.
응용프로그램의 모든 활동을 보려면 사용자가 로그인해야 합니다.사용자는 거의 모든 활동에서 로그아웃할 수 있습니다.이것은 응용 프로그램의 요구 사항입니다.사용자가 로그아웃한 경우 언제든지 로그인으로 사용자를 보내고자 합니다.Activity
이 시점에서 "뒤로" 버튼을 누르면 사용자가 Android의 홈 화면으로 돌아갈 수 있도록 이 작업이 기록 스택의 맨 아래에 있기를 원합니다.
저는 이 질문이 몇 가지 다른 곳에서 질문을 하는 것을 보았고, 모두 비슷한 답변으로 답했습니다(여기서 개략적으로 설명함). 하지만 피드백을 수집하기 위해 이 질문을 여기에 제시하고 싶습니다.
을▁its▁setting▁by▁the다▁i▁opening▁login로 설정하여 열어 보았습니다.Intent
에서 깃발의까지.FLAG_ACTIVITY_CLEAR_TOP
이 작업은 설명서에 설명된 대로 수행되는 것처럼 보이지만 로그인 활동을 기록 스택의 맨 아래에 배치하고 사용자가 이전에 표시된 로그인 활동으로 다시 이동하지 못하도록 하는 제 목표를 달성하지는 못합니다.저는 또한 사용해봤습니다.android:launchMode="singleTop"
매니페스트의 로그인 활동에 대한 것이지만, 이것도 제 목표를 달성하지 못합니다(그리고 어쨌든 아무 영향도 없는 것으로 보입니다).
기록 스택을 지우거나 이전에 열어본 모든 작업을 완료해야 합니다.
한 가지 방법은 각 활동에 대한 정보를 제공하는 것입니다.onCreate
상태를 하고 로그인 상태를 확인합니다.finish()
로그인하지 않은 경우활동이 종료될 때 뒤로 버튼을 계속 사용할 수 있으므로 이 옵션은 마음에 들지 않습니다.
은 다옵션다유것다입니는을 하는 것입니다.LinkedList
모든 곳에서 정적으로 액세스할 수 있는 모든 열린 활동에 대한 참조(약한 참조를 사용하는 참조).로그아웃 시 이 목록에 액세스하여 이전에 연 모든 활동을 반복합니다.finish()
곧 이 할 것입니다저는 아마 곧 이 방법을 실행하기 시작할 것입니다.
차라리 좀 쓰겠습니다Intent
하지만 이를 달성하기 위한 깃발 속임수.위에서 설명한 두 가지 방법 중 하나를 사용하지 않고도 지원서의 요구 사항을 충족할 수 있다는 것을 알게 되어 매우 기쁘게 생각합니다.
다음을 사용하여 이를 달성할 수 있는 방법이 있습니까?Intent
매니페스트 설정 두 " 매페스트설정옵션번째두내유지또니는taining", "지▁settings,번옵,션,유▁a▁or"를 유지합니다.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 **//
}
새로운 Android 프로그래머가 이 문제를 연구하고 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()
'dLoginActivity
스택을 .LoginActivity
답은 다음과 같습니다.@doreamon
이 스레드에서 (적어도 나의 겸손한 눈에는) 최선의 해결책입니다.
https://stackoverflow.com/a/9580057/614880
Login Activity를 활성 상태로 유지할지 여부에 대한 까다로운 의미가 이러한 혼란을 야기하고 있다고 생각합니다.
행운을 빌어요.
갱신하다
퍼슈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 이상을 사용하는 경우 이를 사용할 수 있습니다. -- 이는 현재 발생하고 있는 문제를 정확하게 해결하는 것으로 보입니다.분명히 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_ACTIVE_CLEAR_에 동의합니다.TOP은 원하는 것처럼 들립니다. 실행 중인 활동을 제외한 전체 스택을 지우고, Back(뒤로) 버튼을 누르면 응용 프로그램이 종료됩니다.하지만 Mike Repass가 언급했듯이 FLAG_ACTIVE_CLEAR_TOP은 실행 중인 활동이 이미 스택에 있을 때만 작동합니다. 활동이 없을 때는 플래그가 아무 것도 하지 않습니다.
무엇을 해야 하나?시작 중인 활동을 FLAG_ACTIVE_NEW_TASK와 함께 스택에 넣습니다. 그러면 해당 활동이 기록 스택의 새 작업을 시작합니다.그런 다음 FLAG_ACTIVE_CLEAR_TOP 플래그를 추가합니다.
이제 FLAG_ACTIVE_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();
}
답이 많네요.이것도 도움이 될지도...
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);
승인된 해결책은 올바르지 않습니다. 브로드캐스트 수신기를 사용하는 것은 이 문제에 대한 좋은 생각이 아니기 때문에 문제가 있습니다.활동이 이미 Destroy() 메서드를 호출한 경우 수신기를 받을 수 없습니다.최상의 해결책은 공유 환경설정에 부울 값을 설정하고 활동의 onCreate() 메서드에서 확인하는 것입니다.사용자가 로그인하지 않은 상태에서 호출하지 않아야 하는 경우 활동을 종료합니다.여기 그것에 대한 샘플 코드가 있습니다.매우 간단하고 모든 조건에 적용됩니다.
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;
}
끔가.finish()
않는
저는 그 문제를 해결했습니다.
finishAffinity()
제 앱에서 생각해 낸 해결책이 여기 있습니다.
로그인 활동에서 로그인을 성공적으로 처리한 후 API 수준에 따라 다음 로그인을 다르게 시작합니다.
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);
Gingerbread에서 Main Activity에서 뒤로 버튼을 누르면 Login Activity가 즉시 숨겨집니다.허니콤 이상에서는 로그인을 처리한 후 로그인 활동을 완료하기만 하면 로그아웃을 처리한 후 올바르게 다시 생성됩니다.
저는 이 질문에 대해 다른 접근법을 제안하고 싶습니다.가장 효율적인 것은 아닐 수도 있지만, 적용하기가 가장 쉽고 코드가 거의 필요하지 않다고 생각합니다.첫 번째 활동(로그인 활동의 경우)에 다음 코드를 쓰면 로그아웃 후 사용자가 이전에 시작한 활동으로 돌아갈 수 없습니다.
@Override
public void onBackPressed() {
// disable going back to the MainActivity
moveTaskToBack(true);
}
사용자가 로그인한 직후에 로그인 활동이 종료되어 나중에 뒤로 버튼을 눌러 다시 돌아갈 수 없을 것으로 예상됩니다.대신 사용자가 앱 내에서 로그아웃 버튼을 눌러야 제대로 로그아웃할 수 있습니다.이 로그아웃 버튼은 다음과 같은 단순한 의도를 구현합니다.
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();
모든 제안을 환영합니다.
선택한 답은 영리하고 까다롭습니다.제가 한 방법은 다음과 같습니다.
LoginActivity는 작업의 루트 활동입니다. Android:noHistory="true"를 Manifest.xml에서 설정합니다. SettingsActivity에서 로그아웃하려면 다음과 같이 하면 됩니다.
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);
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);
}
제공된 솔루션 @doreamon은 다음과 같은 경우를 제외한 모든 경우에 정상적으로 작동합니다.
로그인 후 Killing Login 화면 사용자가 중간 화면으로 직접 이동합니다.A->B->C 흐름에서 로그인 ->B ->C ->홈 바로가기 누르기와 같이 탐색합니다.FLAG_ACTIVE_CLEAR_ 사용하기홈(A)이 스택 기록에 없으므로 TOP은 C 활동만 지웁니다.A 화면에서 뒤로를 누르면 B로 돌아갑니다.
이 문제를 해결하려면 작업 스택(Arraylist)을 유지하고 홈을 누르면 이 스택의 모든 작업을 종료해야 합니다.
공유 환경설정 또는 응용프로그램 활동에서 플래그를 관리하여 가능합니다.
앱을 시작할 때(스플래시 화면에서) 플래그 = false를 설정합니다. On Logout Click 이벤트에서는 플래그를 true로 설정하고 모든 활동의 OnResume()에서 플래그가 true인지 확인한 후 call finish)를 선택합니다.
매력적으로 작동합니다 :)
Logout(로그아웃)을 클릭하면 다음과 같이 부를 수 있습니다.
private void GoToPreviousActivity() {
setResult(REQUEST_CODE_LOGOUT);
this.finish();
}
이전 활동의 활동 결과()에서 모든 활동을 완료할 때까지 이 코드를 다시 호출합니다.
한 가지 방법은 각 활동의 로그인 상태를 확인하고 로그인하지 않은 경우 종료()하는 것입니다.활동이 종료될 때 뒤로 버튼을 계속 사용할 수 있으므로 이 옵션은 마음에 들지 않습니다.
onStop() 또는 Pause() 메서드에서 logout()을 호출하고 finish()를 수행합니다.그러면 Android는 더 이상 활동 스택에 포함되지 않으므로 활동이 다시 시작될 때 Create()를 호출해야 합니다.그런 다음, onCreate()에서 로그인 상태를 확인하고 로그인하지 않은 경우 로그인 화면으로 전달합니다.
또 다른 방법은 로그인 상태를 확인하여 로그인하지 않은 경우 로그인 작업을 완료()하고 시작하는 것입니다.
언급URL : https://stackoverflow.com/questions/3007998/on-logout-clear-activity-history-stack-preventing-back-button-from-opening-l
'programing' 카테고리의 다른 글
REGEXP_REplace with MySQL 또는 MariaDB가 와일드카드 일치를 사용하여 빈 문자열을 바꾸지 않음 (0) | 2023.09.03 |
---|---|
Swift에서 어레이의 모든 멤버를 동일한 값으로 초기화하는 방법은 무엇입니까? (0) | 2023.09.03 |
sql 읽기 전용 모드에서 연결 열기 (0) | 2023.08.29 |
'gcc-O2'에서 무한 루프에 최적화된 기능 (0) | 2023.08.29 |
마리아에 대한 스프레드시트DB (0) | 2023.08.29 |