Fragment.setNextAnim(int) on a null object reference

产生的原因:java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.Fragment.setNextAnim(int)' on a null object reference

虽然知道是这个原因,但是呢?我们代码中并没有对MainActivity中的Fragment进入和出入动画做设置,可以这样说,这段代码是谷歌官方的,但是它抛异常


image.png
image.png

影响的结果,app奔溃率的90%的原因都是这个原因。

image.png
image.png

定位问题

Android N 指纹识别 NullPointerException: Attempt toFragment.mNextAnim 的错误 在这个博客下作者一句话:已录制指纹,关闭指纹后重新开启指纹识别,设置停止运行,抛出异常为

java.lang.NullPointerException: Attempt to write to field 'int android.app.Fragment.mNextAnim' on a null object reference

虽然和我们的程序中抛出的异常不一样,但是也是出入动画的为null,解释的原因为:fragment为空的时候hide remove 或是show了,但是这毕竟是谷歌大神写的源码,毫无为空的地方,因为它也不显示到底第几行报错

Like commit() but allows the commit to be executed after an activity’s state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.

大致意思是说我使用的 commit方法是在Activity的onSaveInstanceState()之后调用的,这样会出错,因为
onSaveInstanceState方法是在该Activity即将被销毁前调用,来保存Activity数据的如果在保存完状态后再给它添加Fragment就会出错。
到这里我大概明白什么原因了,就是当onSaveInstanceState()调用以后回来再次commit fragment的话,会导致这个bug的产生,所以在这里入手解决问题!

模拟问题的出现

android3.0之前:onResume() -- [optional]onSaveInstanceState() -- onPause(),即调用onPause()之前,可能调用onSaveInstanceState()
android3.0之后:onResume() -- onPause() -- [optional]onSaveInstanceState() -- onStop(),即调用onStop()之前,可能调用onSaveInstanceState()
就是由于这个可能,花费了很多时间,由于onSaveInstanceState()不是必然出现,所以要模拟出来,开始我的模拟之路!

1、模拟横竖屏的情况(这种情况简单,但是由于项目工程中,在横竖屏上有很多null异常,导致自己修复的时候,很多代码需要注释掉,反而更加麻烦,最后没有完美呈现横屏情况下app的状态分析)

2、模拟MainActivity异常关闭的情况,同时App正常的运行下来,在失去焦点了,2s后开启一个新的Activity同时关闭当前的Activity,但是呢?app不会异常,只不过在栈内最下的位置不是MainActivity了,当返回的时候,就直接退出程序了。

5FXVLX)A{_09PM8`26B7ZTI.png

3、仔细研究到底合适会触发Activity的 onSaveInstanceState() 和 onRestoreInstanceState();

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate()、onPause()等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState() 会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。
onSaveInstanceState()方法会在什么时候被执行:
  (1)、当用户按下HOME键时。
  这是显而易见的,系统不知道你按下HOME后要运行多少其他的程序,自然也不知道activity A是否会被销毁,因此系统会调用onSaveInstanceState(),让用户有机会保存某些非永久性的数据。以下几种情况的分析都遵循该原则
  (2)、长按HOME键,选择运行其他的程序时。
  (3)、按下电源按键(关闭屏幕显示)时。
  (4)、从activity A中启动一个新的activity时。
  (5)、屏幕方向切换时,例如从竖屏切换到横屏时。

更具上面的结论,其实我在不断测试中已经在不断的走onSaveInstanceState(),只不过我自己以为没有走这个方法。但是测试过程中, Fragment.setNextAnim(int)这个bug产生的几率很小,可以忽略不计。所以这里可以得出结论:当onSaveInstanceState()调用以后回来再次commit fragment的话,不会导致这个bug的产生,那么以上的全部都过程,都是不成立的

那到底是什么样的问题导致Fragment.setNextAnim(int) null异常的呢?看下Acitivty的生命周期,当内存不足的时候,app能在后台被后台回收掉,但是Activity并没有被销毁掉,还是存在栈内中,只不过会走onCreate()方法。ok!到这里就可以定位了出问题出现的点

image.png

再次试图重现问题,这次聪明了,直接哪一个内存比较小的手机,不断的启动手机里其他的APP,同时也要启动目标App,然他的进程一直在前台进程和非前台进程中切换,需要注意的是,当启动一个比较耗内存的app比如地图,游戏之类的,会把app直接回收掉,这不是bug,这是安卓系统的原因,同时还需的注意点,在这里我们关心的MainActivity被回收了,所以建议把MainActivity的位置置于在栈内第三个或者是第四个位置,一切准备就绪,开始测试(主要看人品,我个人在测试3次左右就能出现)

image.png

哦原来是,这样子fragment为null,导致了java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.Fragment.setNextAnim(int)' on a null object reference

来个手动的测试的结果,如图

image.png

总结:当Activty别系统紧急回收了,没有被销毁,重新走到onCreate()的方法中了,初始化Fragment的时候,导致fragment的变量为null,就会引起如下bug

java.lang.RuntimeException:Unable to resume activity {cn.changniannian.broodon/cn.changniannian.broodon.view.navigation.main.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.Fragment.setNextAnim(int)' on a null object reference
2 android.app.ActivityThread.performResumeActivity(ActivityThread.java:3030)
3 ......
4 Caused by:
5 java.lang.NullPointerException:Attempt to invoke virtual method 'void android.support.v4.app.Fragment.setNextAnim(int)' on a null object reference
6 android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:768)
7 android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2415)
8 android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2200)
9 android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2153)
10 android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2063)
11 android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)
12 android.support.v4.app.FragmentActivity.onResume(FragmentActivity.java:440)
13 com.broodon.core.base.BaseActivity.onResume(BaseActivity.java:137)
14 cn.changniannian.broodon.view.navigation.main.MainActivity.onResume(MainActivity.java:525)
15 android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1243)
16 android.app.Activity.performResume(Activity.java:6111)
17 android.app.Activity.performResume(Activity.java:6313)
18 android.app.ActivityThread.performResumeActivity(ActivityThread.java:3012)
19 android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3061)
20 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1375)
21 android.os.Handler.dispatchMessage(Handler.java:102)
22 android.os.Looper.loop(Looper.java:135)
23 android.app.ActivityThread.main(ActivityThread.java:5318)
24 java.lang.reflect.Method.invoke(Native Method)
25 java.lang.reflect.Method.invoke(Method.java:372)
26 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:922)
27 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:717)
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容