BUG小结

    xiaoxiao2021-03-25  94

    今天遇到一个bug,现象是Activity启动显示后,锁屏(此时Activity发了一条Message),

    然后亮屏在解锁页面(一直亮着)

    30秒后Handler处理Message>>调用了onTitleBackPressed里的onBakPressed方法,造成的崩溃:

    java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1832) at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:774) at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:178) at com.cmcm.onews.ui.********kVideoActivity.access$101(*****Activity.java:34) at com.cmcm.onews.ui.**************Activity$2.onTitleBackPressed(*****Activity.java:257) 通过在AS打log(关键词GC |***ActivityLog)发现:

    03-11 00:56:09.908 D/***ActivityLog: onResume: 03-11 00:56:12.644 D/***ActivityLog: onPause: 03-11 00:56:12.677 D/***ActivityLog: onSaveInstanceState: 03-11 00:56:12.691 D/***ActivityLog: onStop: 03-11 00:56:30.932 I/art: Background sticky concurrent mark sweep GC freed 36589(2MB) AllocSpace objects, 39(1616KB) LOS objects, 12% free, 23MB/26MB, paused 3.832ms total 101.098ms 03-11 00:56:40.533 D/***ActivityLog: onTitleBackPressed:

    直接原因是:

    在生命周期onSaveInstanceState、onStop之后,人为调用了FragmentActivity的onBackPress()方法

    (本例中是Handler处理Message时调用),

    然后执行FragmentManager里的checkStateLoss()引起的Bug

    private void checkStateLoss() { if (mStateSaved) { throw new IllegalStateException( "Can not perform this action after onSaveInstanceState"); } if (mNoTransactionsBecause != null) { throw new IllegalStateException( "Can not perform this action inside of " + mNoTransactionsBecause); } }查看mStateSaved设置为true的地方,发现FragmentManager有两个地方

    static final boolean HONEYCOMB = android.os.Build.VERSION.SDK_INT >= 11; Parcelable saveAllState() { if (HONEYCOMB) { mStateSaved = true; } ..... } public void dispatchStop() { mStateSaved = true; } 然后分别在源代码FragmentActivity中调用

    protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Parcelable p = mFragments.saveAllState(); } protected void onStop() { super.onStop(); mStopped = true; mHandler.sendEmptyMessage(MSG_REALLY_STOPPED); mFragments.dispatchStop(); }所以生命周期走了onSaveInstanceState 和 onStop,都会将checkStateLoss 中的 mStateSaved设置为true

    (曾经想把onSaveInstanceState重载,写成空方法,所以也不能解这个崩溃,FragmentActivity的特别之处。。。)

    解决方法:

    因此,最后的解决方法回到业务逻辑上,我们在onTitleBackPressed里想退出当前的Activity,

    那么不去调用onBackPressed方法(从而不checkStateLoss()),直接调用finish方法,崩溃解决。。

    从中得出的经验是如果是FragmentActivity,那么手动调用onBackPressed方法,

    需要注意会不会出现在onSaveInstanceState 和 onStop之后调用(普通Activity也需要注意)

    有可能出现崩溃java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

    另外,亮屏在解锁页面,报IllegalStateException异常之后,解锁,Activity直走到onStop后重新启动onCreate(没有走onDestory)

    从03-11 00:56:30.932 I/art: Background sticky concurrent mark sweep GC freed 36589(2MB) AllocSpace objects, 39(1616KB) LOS objects日志看出来

    猜测是GC回收了Activity(App process killed),然后User navigates to the activity,重启Activity

    (Activity生命周期图的左半部分)

    参考:

    https://developer.android.com/guide/components/activities/activity-lifecycle.html

    Android系统那些重要的LOG

    Fragment相关

    转载请注明原文地址: https://ju.6miu.com/read-25807.html

    最新回复(0)