【问题标题】:How to clear Android fragment back stack without resuming intermediate fragments如何在不恢复中间片段的情况下清除 Android 片段回栈
【发布时间】:2015-06-09 18:26:39
【问题描述】:

我需要清除后台堆栈中的所有片段。

问题是我需要确保在某个时间点,堆栈已被成功清除,之后弹出的碎片都不会被恢复。

一些片段显示与当前登录用户相关的内容。 现在,如果用户决定退出,我想清除堆栈,退出用户并将应用程序转换到初始片段。 问题是,堆栈弹出被延迟,在我退出后,一些与用户相关的片段尝试恢复并询问用户配置文件数据。如果没有登录用户,底层 API 会抛出异常。所以片段崩溃了,因为它不应该在这种状态下使用。

我尝试了很多方法:

@Override
public void onSignOutConfirmed() {
    Log.d(TAG, "onSignOutConfirmed");

    getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

    Log.d(TAG, "onSignOutConfirmed - signing out");

    UserProfileService.signOut();
    Analytics.trackEvent(EventType.SIGN_OUT);
    showStartupScreen();
}

@Override
public void onSignOutConfirmed() {
    Log.d(TAG, "onSignOutConfirmed");

    FragmentManager fm = getSupportFragmentManager();

    int backStackCount = fm.getBackStackEntryCount();

    while(backStackCount-- != 0) {
        fm.popBackStackImmediate();
    }

    Log.d(TAG, "onSignOutConfirmed - signing out");

    UserProfileService.signOut();
    Analytics.trackEvent(EventType.SIGN_OUT);
    showStartupScreen();
}

日志显示,当我调用 UserProfileService.signOut() 时,片段仍在处理其生命周期方法。当片段暂停时,检索片段之一的配置文件数据的 AsyncTask 将被取消(带有中断)。但是片段暂停得太晚了。

而且错误并不总是发生。但大多数情况下它会在三星 S2 (Android 4.1.2) 上运行。

06-09 19:46:54.760 D/com.myapp.application.MainActivity( 4562): **onSignOutConfirmed**
06-09 19:46:54.765 D/com.myapp.application.screens.main.MainFragment( 4562): onCreateView
06-09 19:46:54.826 D/com.myapp.application.screens.main.MainFragment( 4562): onCreateAnimation (transit 0, enter true, nextAnim 0)
06-09 19:46:54.831 D/com.myapp.application.screens.main.TranscriptionsFragment( 4562): onCreateView
06-09 19:46:54.856 D/com.myapp.application.screens.main.MainFragment( 4562): onResume
06-09 19:46:54.856 D/com.myapp.application.screens.main.TranscriptionsFragment( 4562): **onResume**
06-09 19:46:54.866 D/com.myapp.application.MainActivity( 4562): **onSignOutConfirmed - signing out**
06-09 19:46:54.876 D/myappDB( 4562): Application settings: id 1.
06-09 19:46:54.876 D/myappDB( 4562): Application settings (id 1): updated, [_activeProfileId] = [null].
06-09 19:46:54.916 D/myappDB( 4562): Application settings: active user profile null.
06-09 19:46:54.941 D/myappDB( 4562): Application settings: active user profile null.
06-09 19:46:54.951 D/com.myapp.application.screens.main.TranscriptionsFragment( 4562): **onPause**
06-09 19:46:54.951 D/com.myapp.application.screens.main.MainFragment( 4562): onPause
06-09 19:46:54.961 D/com.myapp.application.screens.main.TranscriptionsFragment( 4562): onDestroyView
06-09 19:46:54.961 D/com.myapp.application.screens.main.MainFragment( 4562): onDestroyView
06-09 19:46:54.961 D/com.myapp.application.screens.main.MainFragment( 4562): onCreateAnimation (transit 0, enter false, nextAnim 0)
06-09 19:46:55.381 E/AndroidRuntime( 4562):     at com.myapp.application.impls.sqlite.SQLiteApplicationSettingsPersistance.getAndCheckActiveUserProfileId(SQLiteApplicationSettingsPersistance.java:421)
06-09 19:46:55.381 E/AndroidRuntime( 4562):     at com.myapp.application.impls.sqlite.SQLiteTranscriptionPersistance.getTranscriptionStats(SQLiteTranscriptionPersistance.java:54)
06-09 19:46:55.381 E/AndroidRuntime( 4562):     at com.myapp.application.impls.finders.TranscriptionListFinder.getTranscriptions(TranscriptionListFinder.java:45)
06-09 19:46:55.381 E/AndroidRuntime( 4562):     at com.myapp.application.screens.main.TranscriptionsFragment$RetrieveTranscriptionsAsyncTask.doInBackground(TranscriptionsFragment.java:244)
06-09 19:46:55.381 E/AndroidRuntime( 4562):     at com.myapp.application.screens.main.TranscriptionsFragment$RetrieveTranscriptionsAsyncTask.doInBackground(TranscriptionsFragment.java:241)
06-09 19:46:55.421 D/com.myapp.application.screens.main.TranscriptionsFragment( 4562): onDetach

【问题讨论】:

  • developer.android.com/guide/components/fragments.html 向下滚动,检查“生命周期”图形并在您恢复它时注意片段中的 4 个回调 - 您可以在其中发现没有“CURRENT-USER”的事实
  • 但是我不想处理每一个片段的异常情况。它会用不必要的代码污染许多片段。

标签: android android-fragments


【解决方案1】:

试试这个:

private void clearFragmentBackStack() {
    FragmentManager fm = getSupportFragmentManager();
    for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {
        fm.popBackStack();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    相关资源
    最近更新 更多