离开时 StartDestination NullpointerException onSaveInstance

StartDestination NullpointerException onSaveInstance when navigated away

我有一个在两个片段之间导航的抽屉布局(就像在使用抽屉布局创建新项目时设置的一样:所以有一个导航图和 AppBarConfiguration 的一般设置。我刚刚删除了一大堆的东西,这样我最终只会得到两个片段)。

问题:当我导航到第二个片段并更改设备方向两次(因此翻转 phone 横向,然后返回纵向)然后我在起始目的地的 onSavedInstanceState 中得到一个 nullpointerException () 方法。我想知道为什么会这样?有没有办法弹出该片段或其他东西,因为它甚至不可见?我有点希望导航 UI 能够正确处理这个问题,因为我认为这是它的目的 - 但是,现在我觉得我可能遗漏了一些真正重要的东西

导航图:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/nav_home">

<fragment
    android:id="@+id/nav_home"
    android:name="SomeNameHome"
    android:label="@string/menu_auction"
    tools:layout="@layout/fragment_auction" />

<fragment
    android:id="@+id/nav_gallery"
    android:name="SomeNameGallery"
    android:label="@string/menu_basket"
    tools:layout="@layout/fragment_basket" />

</navigation>

然后,首页Activity:

/** Activity containing the Auction and Basket fragments. */
public class HomeActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_gallery)
                .setDrawerLayout(drawer)
                .build();
        navigationView.setItemIconTintList(null);
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }
}

问题代码,在起始目标片段中:

 @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        LinearLayoutManager m = (LinearLayoutManager) mSearchResultsList.getLayoutManager();
        outState.putInt(SAVED_INSTANCE_POSITION, m.findFirstCompletelyVisibleItemPosition() );
    }

mSearchResultList 在第二次方向更改时为空。

今天发现了一些新东西:

"If you make state restorations in the onCreateView() or in the onViewCreated(), it will be lost in case of a double orientation change when the fragment is in the backstack. Actually, after the first change, the state will be saved then lost because only the onCreate() will pass. The second orientation change will then triggers the onSaveInstanceState() on a null state."

来自这篇文章:https://medium.com/@jacquesgiraudel/problem-with-restoring-fragments-from-the-backstack-945dc3f7f5a5

它进一步建议: "if your fragment is backstack-able, make your state restorations in the onCreate()"

好了,好了!希望这能帮助和我犯同样错误的其他人!