我有片段的backStack问题。首先,我的结构是:我有使用fragmentManager的活动,使用方法add()添加的新片段以及添加到后台堆栈。所以,当我在backstack中列出2个片段时,当我更改方向时,重新创建活动,并恢复片段,但是当我调用 onBackPressed()并调用 popBackStackImmediate()我得到一个异常: java.lang.NullPointerException:尝试调用虚方法' void android.support.v4.app.Fragment.setNextAnim(int)'在空对象引用上。
似乎我们在后台堆栈中有空片段,但是我已经检查过了,这些片段并不是空的。那么,你能帮忙解决这个问题吗?
我添加这样的片段:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
if (previousFragment != null) {
fragmentTransaction.hide(previousFragment);
}
fragmentTransaction.add(containerViewId, fragment, fragmentTag)
.addToBackStack(fragmentTag)
.commit();
在onBackPressed()中我有相同的行为:
if (fragmentManager.getBackStackEntryCount() == 1) {
finish();
} else {
super.onBackPressed();
}
完整的stackTrace是:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.Fragment.setNextAnim(int)' on a null object reference
at android.support.v4.app.BackStackRecord.executePopOps(BackStackRecord.java:826)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2587)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2377)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2332)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:851)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:794)
at net.lampa.tablet.nightexpress.view.activities.OrderFinalActivity.onBackPressed(OrderFinalActivity.java:147)
at net.lampa.tablet.nightexpress.view.activities.OrderFinalActivity.onOptionsItemSelected(OrderFinalActivity.java:183)
at android.app.Activity.onMenuItemSelected(Activity.java:2914)
at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:380)
at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
at android.support.v7.widget.ToolbarWidgetWrapper$1.onClick(ToolbarWidgetWrapper.java:187)
at android.view.View.performClick(View.java:5204)
at android.view.View$PerformClick.run(View.java:21153)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
第164行是:
super.onBackPressed()
添加逻辑的基本活动的完整代码:
public abstract class BaseActivity extends AppCompatActivity {
private Unbinder uninder;
protected BaseFragment currentFragment;
protected BaseFragment previousFragment;
protected FragmentManager fragmentManager;
private Map<Integer, ArrayList<String>> filterTagsMap = new TreeMap<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Class cls = getClass();
if (!cls.isAnnotationPresent(Layout.class)) {
return; // Layout annotation is required
}
Annotation annotation = cls.getAnnotation(Layout.class);
setContentView(((Layout) annotation).id());
uninder = ButterKnife.bind(this);
if(fragmentManager == null) {
fragmentManager = getSupportFragmentManager();
}
currentFragment = getDefaultFragment();
inject(); // inject dependencies
setupDefaultValues();
}
public ApplicationComponent getApplicationComponent() {
return ((NEApplication) getApplication()).getApplicationComponent();
}
public abstract void setupDefaultValues();
public void closeCurrentFragmentInBackStack() {
fragmentManager.popBackStackImmediate();
}
public void showFragment(int containerViewId, BaseFragment fragment, boolean needToRefreshBackStack) {
if (needToRefreshBackStack && fragmentManager.getBackStackEntryCount() > 0) {
int indexToDelete = (fragment.getClass().getSimpleName()
.equals(fragmentManager.getBackStackEntryAt(0).getName())) ? 0 : 1;
int backStackFragmentsCount = fragmentManager.getBackStackEntryCount();
for (int i = backStackFragmentsCount - 1; i >= indexToDelete; i--) {
int backStackId = fragmentManager.getBackStackEntryAt(i).getId();
fragmentManager.popBackStack(backStackId, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}
previousFragment = currentFragment;
currentFragment = fragment;
String fragmentTag = fragment.getClass().getSimpleName();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
if (previousFragment != null) {
fragmentTransaction.hide(previousFragment);
}
fragmentTransaction.add(containerViewId, fragment, fragmentTag)
.addToBackStack(fragmentTag)
.commit();
}
protected abstract BaseFragment getDefaultFragment();
@Override
protected void onDestroy() {
uninder.unbind();
uninder = null;
super.onDestroy();
}
}
答案 0 :(得分:0)
弹出片段本身的条件是逻辑反过来写的。如果片段存在于backstack中,super.onBackPressed()
将弹出片段。如果getBackStackEntryCount()
大于零,则需要调用super方法,否则当{{1}中没有片段时完成活动}}
backstack