Programing

전체 기록 스택을 지우고 Android에서 새로운 활동을 시작하십시오.

lottogame 2020. 3. 10. 08:19
반응형

전체 기록 스택을 지우고 Android에서 새로운 활동을 시작하십시오.


스택에서 활동을 시작하여 전체 히스토리를 지우는 것이 가능합니까?

그 상황

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"솔루션은 참으로 순수 해커입니다. 그렇게하지 말아야합니다. :)

편집 : @ Ben Pearson 의 의견에 따라 API <= 10의 경우 이제 동일한 목적으로 IntentCompat 클래스를 사용할 수 있습니다 . IntentCompat.FLAG_ACTIVITY_CLEAR_TASK플래그를 사용 하여 작업을 지울 수 있습니다 . 따라서 사전 API 레벨 11도 지원할 수 있습니다.


사례 1 : 두 가지 활동 A와 B 만 :

여기에서 활동 흐름은 A-> B입니다 .B에서 백 버튼을 클릭하면 응용 프로그램을 닫고 A에서 액티비티 B를 시작하는 동안 finish ()를 호출하면 android가 액티비티 A를 Backstack에 저장하지 못하게됩니다. 응용 프로그램의 Loding / Splash 화면.

Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();

사례 2 : 두 가지 이상의 활동 :

A-> B-> C-> D-> B와 같은 흐름이 있고 활동 D에서 오는 동안 활동 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);

여기서 Intent.FLAG_ACTIVITY_CLEAR_TOP 및 Intent.FLAG_ACTIVITY_NEW_TASK 때문에 스택 B가 새 인스턴스가 아닌 백 스택에서 시작되어 스택을 지우고 맨 위로 만듭니다. 따라서 뒤로 버튼을 누르면 전체 응용 프로그램이 종료됩니다.


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이 스택에서 새로운 활동을 찾으면 모든 것이 지워지기 전에 거기에 있고 풀려납니다.

여기 내 로그 아웃 기능이 있습니다. 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();
}

스택을 변경해서는 안됩니다. Android 뒤로 버튼은 웹 브라우저에서와 같이 작동해야합니다.

나는 그것을 할 수있는 방법을 생각할 수 있지만 그것은 꽤 해킹입니다.

  • 활동 singleTaskAndroidManifest예제 에 추가 하여 활동 만드십시오 .

    <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스택에서 원하지 않는 활동을 제거합니다.


때로는 안드로이드 에뮬레이터가 Eclipse DDMS 도구를 연결하지 못하고 adb가 수동으로 시작하도록 요청할 수 있습니다. 이 경우 명령 프롬프트를 사용하여 adb를 시작하거나 중지 할 수 있습니다.

참고 URL : https://stackoverflow.com/questions/3473168/clear-the-entire-history-stack-and-start-a-new-activity-on-android

반응형