activity生命周期-进阶版(除了onCreate...onDestroy这些还有什么?)
2017-09-22 10:57
731 查看
时隔两年,我对于activity的生命周期非但未变得清晰,反而越来越疑惑。除了普通生命周期方法:onStart(),onRestart(),onCreate(),onResume(),onPause(),onStop(),onDestroy()这些,其实activity启动时,还有一些隐藏的,系统一定会调用的方法。
事实上,一些优秀的开源项目会重写这些方法,完成一些必要的操作,而我在看到这些方法,除了牛掰,大概看的懂之外,再无其他的感受了。
以下方法,也是系统一定会调用的方法:
onApplyThemeResource(Theme theme, int resid, boolean first)
onContentChanged()
onPostCreate()
onPostResume()
onAttachedToWindow()
onWindowFocusChanged(boolean hasFocus)
onDetachedFromWindow()
以下几个问题是一定要搞清楚的,为了我的生命周期大业:
这些方法和生命周期夹杂在一起,哪个先,哪个后?当对话框弹出来,会调用哪些?当应用进入后台,会调用哪些?
哪些获得的window是不为空的?
哪些进行数据处理,会对界面显示造成影响?(黑白屏,无焦点)
哪些可以对view进行初始化?
哪些可以获得控件的尺寸?
我想,这非常重要,此后还会特别关注view的生命周期。此次主要对以上问题进行测试,并进行结果记录。
onApplyThemeResource()
onContentChanged()
onCreate()
onStart()
onResume()
onPostResume()
onAttachedToWindow()
onWindowFocusChanged()
dialog弹出,关闭:
都只调用onWindowFocusChanged,额,onPause呢?难道7.0不用了?换个手机再试试。好吧,现在很多手机在dialog启动的时候不会onPause了,就调用了onWindowFocusChanged,看来课本什么的也不一定靠谱。或许有些型号依旧满足失去焦点会调用onPause,但我试的小米,红米都不会。
退出activity:
onPause()
onWindowFocusChanged()
onStop()
onDestroy()
onDetachedFromWindow()
注意,退出时onDetachedFromWindow()是在onDestroy()之后调用的。
转屏:
onPause()
onStop()
onDestroy()
onDetachedFromWindow()
onApplyThemeResource()
onContentChanged()
onCreate()
onStart()
onResume()
onPostResume()
onAttachedToWindow()
onWindowFocusChanged()
网上看到其他人测试会调用到onPostCreate(),但是我的真的没有,看来这个方法并不完全靠谱,决定弃疗。
onApplyThemeResource()DecorView@9f4f736[]
onContentChanged()DecorView@9f4f736[]
onCreate()DecorView@9f4f736[]
onStart()DecorView@9f4f736[]
onResume()DecorView@9f4f736[]
onPostResume()DecorView@9f4f736[]
onAttachedToWindow()DecorView@9f4f736[LifecycleActivity]
onWindowFocusChanged()DecorView@9f4f736[LifecycleActivity]
onPause()DecorView@9f4f736[LifecycleActivity]
onWindowFocusChanged()DecorView@9f4f736[LifecycleActivity]
onStop()DecorView@9f4f736[LifecycleActivity]
onDestroy()DecorView@9f4f736[LifecycleActivity]
onDetachedFromWindow()DecorView@9f4f736[LifecycleActivity]
发现了么?方括号里面的是DectorView绑定的activity,可以看到,这个DctorView确实挺特殊,从onAttatchToWindow以后就一直和activity处于绑定状态,包括onDestroy
当需要获取状态栏,标题栏高度的时候,可以用它,我记得应用要截屏的时候,也有用到,这时候注意放在onAttachedToWindow了。
状态栏,标题栏
屏幕截图:
代替。
效果:
onStart()-黑屏卡死
onRestart()-卡死无黑屏
onResume()-黑屏卡死
onCreate()-黑屏卡死
onStop()-无影响
onPause()-黑屏卡死
onDestroy()-无影响
onApplyThemeResource()-黑屏卡死
onContentChanged()-黑屏卡死
onPostResume()-黑屏卡死
onAttachedToWindow()-黑屏卡死
onWindowFocusChanged()-无影响
onDetachedFromWindow()-无影响
可见启动过程中,唯一对于略多数据处理没有影响的就是onWindowFocusChanged(),关闭过程中,onStop(),onDestroy(),onDetachedFromWindow()无影响。让我略惊讶的是,onCreate方法中,进行这种处理也会卡死,如果这个数据降到100,对于卡死的方法效果会不同吗?
通过测试发现,其实那些卡死的在少量数据的情况下,或许会略卡顿,但是不会太明显,onCreate是一样的,卡顿效果略改善。所以对于少量数据处理,还是放在onCreate方法中更妥当一些。如果数据量略大,可考虑放在onAttachToWindow(),但是还有个问题,就是失去焦点时也会调用这个方法,需要添加一些条件判断。如果数据量庞大,还是放在异步中处理更妥善一些。
onContentChanged()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onCreate()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onStart()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onResume()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onPostResume()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onAttachedToWindow()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onWindowFocusChanged()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onPause()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. …….. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onWindowFocusChanged()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. …….. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onStop()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. …….. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onDestroy()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. …….. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onDetachedFromWindow()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……ID 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
可以看到,除了onApplyThemeResource都可以获取到view,不过应该不是每个都能对view进行操作吧,试试setText(),结果是,真的都可以!
onContentChanged()0
nCreate()0
onStart()0
onResume()0
onPostResume()0
onAttachedToWindow()0
onWindowFocusChanged()600
onPause()600
onWindowFocusChanged()600
onStop()600
onDestroy()600
onDetachedFromWindow()600
可以看到,onWindowFocusChanged是创建过程中唯一可以获得正确的尺寸的。
说几点关键的:
onAttachedToWindow()-decorView开始不为空,可用于获取状态栏高度等,以后重写后我要把它变成onAttachedDecorView(),便于理解。
onWindowFocusChanged-true可以用来获取尺寸,以及略多的数据初始化,false可以当onPause用
onStart/onResume/onRestart这些还是不要随便用,可以用onWindowFocusChanged(true)代替,这个方
bb89
法可以处理稍大些的数据,用户体验应该较好。重写时会将true的时候分到onStartDataDimen(),false时分到onPauseDataDimen(),容易记忆。
因为每次打开界面(包括打开dialog)onWindowFocusChanged,home键都会被调用,还可以用于作用于数据保存和恢复,放在intent里面就可以了:
这部分可以放到onCreate():
比onCreate+onSaveInstance靠谱多了,哈哈,这个方法好万能啊,还不会卡顿。
ps:以前都是用post获取的宽高,自定义组件多了白屏就延时加载,呵呵,测过之后被自己蠢哭了T T.
事实上,一些优秀的开源项目会重写这些方法,完成一些必要的操作,而我在看到这些方法,除了牛掰,大概看的懂之外,再无其他的感受了。
以下方法,也是系统一定会调用的方法:
onApplyThemeResource(Theme theme, int resid, boolean first)
onContentChanged()
onPostCreate()
onPostResume()
onAttachedToWindow()
onWindowFocusChanged(boolean hasFocus)
onDetachedFromWindow()
以下几个问题是一定要搞清楚的,为了我的生命周期大业:
这些方法和生命周期夹杂在一起,哪个先,哪个后?当对话框弹出来,会调用哪些?当应用进入后台,会调用哪些?
哪些获得的window是不为空的?
哪些进行数据处理,会对界面显示造成影响?(黑白屏,无焦点)
哪些可以对view进行初始化?
哪些可以获得控件的尺寸?
我想,这非常重要,此后还会特别关注view的生命周期。此次主要对以上问题进行测试,并进行结果记录。
1.执行顺序
启动执行顺序:(注意onPostCreate()未被调用)onApplyThemeResource()
onContentChanged()
onCreate()
onStart()
onResume()
onPostResume()
onAttachedToWindow()
onWindowFocusChanged()
dialog弹出,关闭:
都只调用onWindowFocusChanged,额,onPause呢?难道7.0不用了?换个手机再试试。好吧,现在很多手机在dialog启动的时候不会onPause了,就调用了onWindowFocusChanged,看来课本什么的也不一定靠谱。或许有些型号依旧满足失去焦点会调用onPause,但我试的小米,红米都不会。
退出activity:
onPause()
onWindowFocusChanged()
onStop()
onDestroy()
onDetachedFromWindow()
注意,退出时onDetachedFromWindow()是在onDestroy()之后调用的。
转屏:
onPause()
onStop()
onDestroy()
onDetachedFromWindow()
onApplyThemeResource()
onContentChanged()
onCreate()
onStart()
onResume()
onPostResume()
onAttachedToWindow()
onWindowFocusChanged()
网上看到其他人测试会调用到onPostCreate(),但是我的真的没有,看来这个方法并不完全靠谱,决定弃疗。
2.哪些window不为空?
好吧,getWindow()都不为空,那么onAttachToWindow()的意义何在?试试getDecorView,终于有用了,测试结果:onApplyThemeResource()DecorView@9f4f736[]
onContentChanged()DecorView@9f4f736[]
onCreate()DecorView@9f4f736[]
onStart()DecorView@9f4f736[]
onResume()DecorView@9f4f736[]
onPostResume()DecorView@9f4f736[]
onAttachedToWindow()DecorView@9f4f736[LifecycleActivity]
onWindowFocusChanged()DecorView@9f4f736[LifecycleActivity]
onPause()DecorView@9f4f736[LifecycleActivity]
onWindowFocusChanged()DecorView@9f4f736[LifecycleActivity]
onStop()DecorView@9f4f736[LifecycleActivity]
onDestroy()DecorView@9f4f736[LifecycleActivity]
onDetachedFromWindow()DecorView@9f4f736[LifecycleActivity]
发现了么?方括号里面的是DectorView绑定的activity,可以看到,这个DctorView确实挺特殊,从onAttatchToWindow以后就一直和activity处于绑定状态,包括onDestroy
当需要获取状态栏,标题栏高度的时候,可以用它,我记得应用要截屏的时候,也有用到,这时候注意放在onAttachedToWindow了。
状态栏,标题栏
Rect frame = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); int statusBarHeight = frame.top; Rect frame = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); int statusBarHeight = frame.top
屏幕截图:
public static Bitmap captureScreen(Activity activity) { activity.getWindow().getDecorView().setDrawingCacheEnabled(true); Bitmap bmp=activity.getWindow().getDecorView().getDrawingCache(); return bmp; }
3.对于略耗时的操作,哪些对界面有影响哪些没有?
我这里指的略耗时,并不是像网络请求这种的,而是循环次数较多,数据略庞大,这里用:for(int i = 0; i < 1000000; i++){ Log.e(TAG,"onPause()"+getWindow().getDecorView()); }
代替。
效果:
onStart()-黑屏卡死
onRestart()-卡死无黑屏
onResume()-黑屏卡死
onCreate()-黑屏卡死
onStop()-无影响
onPause()-黑屏卡死
onDestroy()-无影响
onApplyThemeResource()-黑屏卡死
onContentChanged()-黑屏卡死
onPostResume()-黑屏卡死
onAttachedToWindow()-黑屏卡死
onWindowFocusChanged()-无影响
onDetachedFromWindow()-无影响
可见启动过程中,唯一对于略多数据处理没有影响的就是onWindowFocusChanged(),关闭过程中,onStop(),onDestroy(),onDetachedFromWindow()无影响。让我略惊讶的是,onCreate方法中,进行这种处理也会卡死,如果这个数据降到100,对于卡死的方法效果会不同吗?
通过测试发现,其实那些卡死的在少量数据的情况下,或许会略卡顿,但是不会太明显,onCreate是一样的,卡顿效果略改善。所以对于少量数据处理,还是放在onCreate方法中更妥当一些。如果数据量略大,可考虑放在onAttachToWindow(),但是还有个问题,就是失去焦点时也会调用这个方法,需要添加一些条件判断。如果数据量庞大,还是放在异步中处理更妥善一些。
4.获取view,哪些为空?
onApplyThemeResource()nullonContentChanged()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onCreate()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onStart()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onResume()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onPostResume()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onAttachedToWindow()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-0,0 #7f0c0060 app:id/btn_lifecycle_dialog}
onWindowFocusChanged()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……I. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onPause()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. …….. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onWindowFocusChanged()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. …….. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onStop()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. …….. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onDestroy()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. …….. 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
onDetachedFromWindow()android.support.v7.widget.AppCompatButton{227e6023 VFED..C. ……ID 0,0-600,240 #7f0c0060 app:id/btn_lifecycle_dialog}
可以看到,除了onApplyThemeResource都可以获取到view,不过应该不是每个都能对view进行操作吧,试试setText(),结果是,真的都可以!
5.控件尺寸:
当然onApplyThemeResource因为获得view为null不可以,就不试了,我这里简单粗暴,直接getWidth()获取控件宽度。onContentChanged()0
nCreate()0
onStart()0
onResume()0
onPostResume()0
onAttachedToWindow()0
onWindowFocusChanged()600
onPause()600
onWindowFocusChanged()600
onStop()600
onDestroy()600
onDetachedFromWindow()600
可以看到,onWindowFocusChanged是创建过程中唯一可以获得正确的尺寸的。
总结
所实话,这次测试受益很大,尤其是dialog弹出那里,原来有些手机除了销毁已经不怎么用onPause了,这个方法既然在有的手机内不能作为失去焦点的依据,那么以后就要把onWindowFocusChanged(false)当做onPause用了。说几点关键的:
onAttachedToWindow()-decorView开始不为空,可用于获取状态栏高度等,以后重写后我要把它变成onAttachedDecorView(),便于理解。
onWindowFocusChanged-true可以用来获取尺寸,以及略多的数据初始化,false可以当onPause用
onStart/onResume/onRestart这些还是不要随便用,可以用onWindowFocusChanged(true)代替,这个方
bb89
法可以处理稍大些的数据,用户体验应该较好。重写时会将true的时候分到onStartDataDimen(),false时分到onPauseDataDimen(),容易记忆。
因为每次打开界面(包括打开dialog)onWindowFocusChanged,home键都会被调用,还可以用于作用于数据保存和恢复,放在intent里面就可以了:
@Override public void onWindowFocusChanged(boolean hasFocus) {//可以 super.onWindowFocusChanged(hasFocus); Log.e(TAG,"onWindowFocusChanged()"+getIntent()+num); if(hasFocus) { num = getIntent().getIntExtra("num", 0); boolean isFirst = getIntent().getBooleanExtra("isFirst",true); if(isFirst){ num = 5; getIntent().putExtra("isFirst",false); } }else getIntent().putExtra("num",num); }
这部分可以放到onCreate():
boolean isFirst = getIntent().getBooleanExtra("isFirst",true); if(isFirst){ num = 5; getIntent().putExtra("isFirst",false); }
比onCreate+onSaveInstance靠谱多了,哈哈,这个方法好万能啊,还不会卡顿。
ps:以前都是用post获取的宽高,自定义组件多了白屏就延时加载,呵呵,测过之后被自己蠢哭了T T.
相关文章推荐
- Activity生命周期 onCreate onResume onStop onPause (转)
- Activity生命周期:onCreate onStart onResume onPause onStop onDestory (1) 启动Activity: onCreate onStart onR
- activity反复进入onDestroy onCreate方法
- Activity生命周期 onCreate onResume onStop onPause
- Activity的生命周期中onPause()方法和onSaveInstanceState(Bundle outState)方法比较
- 除了代码我们还有什么
- Activity生命周期之onsaveinstancestate
- activity生命周期的onPause和onStop
- 从打车到专车,滴滴们除了烧钱还有什么?
- Android Activity为什么要细化出onCreate、onStart、onResume、onPause、onStop、onDesdroy这么多方法让应用去重载?
- 重新认识Activity(一)生命周期方法(系统垃圾回收机制和onSaveInstanceState)
- onWindowFocusChange与Activity生命周期之间的关系
- android 中Activity的onStart()和onResume()的区别是什么
- 什么情况下,Activity的onNewInstent()方法会执行?Activity的启动模式相关
- activity调用onCreate()方法后没有调用onStart()方法
- 关于Activity的生命周期和onsaveinstancestate很好的两篇文章
- 安卓中Activity的onStart()和onResume()的区别是什么
- ActivityLifecycleCallbacks,Android API Level >=14 无需手工干涉,监控Activity 运行情况(onCreate,OnStart...等)
- 现场|除了谷歌AI中国中心成立的重磅消息,谷歌开发者大会现场还有这些
- onAttachedToWindow()在整个Activity生命周期的位置及使用