开发者

Why is NPE thrown when finishing Activity?

I have an error that has been driving me crazy for days. Unfortunately, I can not show you the code for two reason, my boss will not appreciate it and the codebase is too large to share. The error occurs whenever the Activity is finishing. Weather it be because I call finish() or because the os destroys it.

The question is, what is (or could) cause execPendingActions() in FragmentManagerImpl to throw a NPE at line 1196.

Here is the stacktrace:

FragmentManagerImpl.execPendingActions() line: 1196 
FragmentManagerImpl$1.run() line: 375   
Handler.handleCallback(Message) line: 587   
Handler.dispatchMessage(Message) line: 92   
Looper.loop() line: 126 
ActivityThread.main(String[]) line: 3997    
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
Method.invoke(Object, Object...) line: 491  
ZygoteInit$MethodAndArgsCaller.run() line: 841  
ZygoteInit.main(String[]) line: 59开发者_如何学C9 
NativeStart.main(String[]) line: not available [native method]  


When talking about finishing the activities: Are you trying to finish() the activity from a View? Are correctly sending MyClass.this.finish()?

It looks to me that OS force it to close due NPE. Something is wrong with the fragments. Something is Null among them. Could you at least paste the line where it crashes?


You may be hitting a bug in fragment manager where it doesn't clear its list of pending transactions before being destroyed. This can happen if you commit a transaction after your state has been saved, using FragmentTransaction.commitAllowingStateLoss(). You may be able to work around it with this code in your activity:

@Override void onDestroy() {
    getFragmentManager().executePendingTransactions();
    super.onDestroy();
}


You could try using the compat library and debugging that.

Alternatively try and reproduce in a cut down sample app.


The NullPointerException is caused by the fact that Activity's Handler is unset from the FragmentManager, so a "solution" that will prevent the crash is the following:

public void onDestroy(){ 
        super.onDestroy(); 
        try { 
            Field mActivityField = getFragmentManager().getClass().getDeclaredField("mActivity");
            mActivityField.setAccessible(true);
            mActivityField.set(getFragmentManager(), this);

            Field mPendingActionsField = getFragmentManager().getClass().getDeclaredField("mPendingActions");
            mPendingActionsField.setAccessible(true);
            mPendingActionsField.set(getFragmentManager(), null);


            Field f = Activity.class.getDeclaredField("mHandler");
            f.setAccessible(true);
            Handler handler = (Handler) f.get(this);
            handler.close(); 
        } catch (Throwable e) {

        } 
} 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜