Android的FragmentManager BackStackRecord.run抛出NullPointerException异常抛出、异常、FragmentManager、Android

2023-09-11 20:22:23 作者:安於現狀°づ

EDIT2: 下面回答我自己的问题

与片段工作时,我有时会收到以下异常:

 九月11号至15日:04:21.023:E / AndroidRuntime(4057):致命异常:主要
九月11号至15号:04:21.023:E / AndroidRuntime(4057):显示java.lang.NullPointerException
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在android.support.v4.app.BackStackRecord.run(BackStackRecord.java:591)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在android.support.v4.app.FragmentManagerImpl $ 1.运行(FragmentManager.java:420)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在android.os.Handler.handleCallback(Handler.java:615)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在android.os.Handler.dispatchMessage(Handler.java:92)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在android.os.Looper.loop(Looper.java:137)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在android.app.ActivityThread.main(ActivityThread.java:4745)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在java.lang.reflect.Method.invokeNative(本机方法)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在java.lang.reflect.Method.invoke(Method.java:511)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:786)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
九月11号至15号:04:21.023:E / AndroidRuntime(4057):在dalvik.system.NativeStart.main(本机方法)
 

我似乎无法弄清楚到底是什么造成的?我认为这是与没有被删除的片段时清理右片段的backstack。

EDIT1:则会出现异常的run() BackStackRecord 被称为通 execPendingTransactions ()。当它试图从管理器中删除片段。

 案例OP_REMOVE:{
  片f = op.fragment;
  f.mNextAnim = op.exitAnim; < ----
  mManager.removeFragment(F,mTransition,mTransitionStyle);
}
打破;
 

解决方案

回答我的问题:

这个例外是(最终),当你调用FragmentTransaction.remove(空)抛出;和FragmentTransaction.commit();

编辑:而且,像两次盘旋和shinyuX指出的评论;调用.show(空)或。新增(空)的时候,连接(空)和.detach(空)的方法,大概也.hide(空)

在调用commit()之后,交易将被排队在FragmentManager。这样一来,当操作处理后显式调用FragmentManager.executePendingTransactions(),或当FragmentManager队列线程调用它,它抛出一个NullPointerException异常。

Android Fragment的使用方法 翻译

在我的情况,我是保持片段州一个全局对象。在那里,我检查,如果该片段显示与否,再除去可见的碎片。但是,因为我开始了新的FragmentActivity,这些国家仍然设置为true,而他们是不可见的。因此,这是一个设计错误。

其他然后固定的设计错误,解决方法很简单:检查FragmentManager.findFragmentByTag()删除片段之前返回null

EDIT2: Answered my own question below

I sometimes get the following exception when working with Fragments:

11-15 09:04:21.023: E/AndroidRuntime(4057): FATAL EXCEPTION: main
11-15 09:04:21.023: E/AndroidRuntime(4057): java.lang.NullPointerException
11-15 09:04:21.023: E/AndroidRuntime(4057):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:591)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at android.os.Handler.handleCallback(Handler.java:615)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at android.os.Handler.dispatchMessage(Handler.java:92)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at android.os.Looper.loop(Looper.java:137)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at android.app.ActivityThread.main(ActivityThread.java:4745)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at java.lang.reflect.Method.invokeNative(Native Method)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at java.lang.reflect.Method.invoke(Method.java:511)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-15 09:04:21.023: E/AndroidRuntime(4057):     at dalvik.system.NativeStart.main(Native Method)

I can't seem to figure out what exactly is causing this? I think it has to do with the backstack of fragments not being cleaned up right when removing fragments.

EDIT1: The exception occurs when run() of BackStackRecord is called thru execPendingTransactions(). When it tries to remove a fragment from the manager.

case OP_REMOVE: {
  Fragment f = op.fragment;
  f.mNextAnim = op.exitAnim; <----
  mManager.removeFragment(f, mTransition, mTransitionStyle);
}
break;

解决方案

Answering my own question:

This exception is (eventually) thrown when you call FragmentTransaction.remove(null); and FragmentTransaction.commit();

EDIT: And also, like Twice Circled and shinyuX point out in the comment; when calling the .show(null) or .add(null), attach(null) and .detach(null) methods, and probably also .hide(null)

After calling commit(), the transaction will be queued in the FragmentManager. As a result, when the operation is being processed after you explicitly call FragmentManager.executePendingTransactions(), or when the FragmentManager queue thread calls it, it throws a NullPointerException.

In my case, I was maintaining fragment states in a global object. There I checked if the fragment was showing or not, and then removed visible fragments. But because I started a new FragmentActivity, these states were still set to true while they were not visible. So this is a design error.

Other then fixing the design error, the solution was simple: check if FragmentManager.findFragmentByTag() returned null before removing the fragment.