Activit、Fragment的生命周期 及横竖屏切换的一些问题 及解决方案

Activity 的生命周期:

1.onCreate():表示Activity 正在被创建 第一个方法
加载一些界面布局文件,初始化Activity

2.onRestart(): 重新启动

3.onStart():当前Activity 正在启动 即将开始 已经可见了。还没有出现在前台还无法与用户进行交互

4.onResume(): 表示已经可见了。已经可以和用户进行交互了

5.onPause(): 表示已经停止了,acitivity 已经不可见了,正常情况下 下面会调用OnStop的方法 如果快速调用的话 会回到当前的Activity 中

6.onStop(): 即将停止 可以做一些稍微重量级的回收工作,不能做太耗时的工作

7.onDestroy(): 表示Activity即将被销毁 这是activity生命周期中最后一个回调 可以做些一些回收工作和最终的资源释放

横竖屏切换Activity的时候走的生命周期:
Activity 会被销毁 onPause,onStop,onDestroy均会被调用,首先onSaveInstanceState来保存当前Activity的状态然后调用onstop-onDestroy-onCreate(有可能是空的)-onRestoreInstanceState(只要走这个方法那就是有数据的,可以进行数据恢复)可以恢复TextView的数据,listView 的访问位置等等

设置旋转屏幕不重新走生命周期可以在清单文件的activity中设置 androdi:configChanges=“orientation (屏幕悬转)| locale(本地位置发生改变)keyboardHidden(掉出了键盘)|screenLayout(屏幕布局发生了改变调用了另一个显示设备)|fontScale(换了一个新的字号)|ScreenSize(屏幕的尺寸信息)|smallestScreenSize(物理屏幕发生改变)”

当横竖屏切换的时候一般情况下 Activity会被销毁然后重新创建 也可以阻止

Activity 的四大启动模式

1.standard 默认模式,标准模式,不管任务栈中是否有这个实例的存在 都是新建一个实例出来 A 调用B ,会把B的实例创建在A 所在的任务栈中 ABCD 再次启动就是ABCDD
2.singleTop 栈顶模式 ABCD 再次启动D 还是ABCD
3.singleTask 栈内复用模式 系统会回调onNewIntent 清除上面的栈
4.singleInstance 单实例模式 加强版的singleTask

fragment 的生命周期

1.onAttach() 关联 Fragment和Activity建立关联的时候调用,被附加到Activity中去。

2.onCreate() 创建 系统会在创建Fragment时调用此方法。可以初始化一段资源文件等等。

3.onCreateView() 创建视图 系统会在Fragment首次绘制其用户界面时调用此方法。 要想为Fragment绘制 UI,从该方法中返回的 View 必须是Fragment布局的根视图。如果Fragment未提供 UI,您可以返回 null。

4.onViewCreated() 在Fragment被绘制后,调用此方法,可以初始化控件资源。

5.onActivityCreated() 当onCreate(),onCreateView(),onViewCreated()方法执行完后调用,也就是Activity被渲染绘制出来后。

6.onPause() 系统将此方法作为用户离开Fragment的第一个信号(但并不总是意味着此Fragment会被销毁)进行调用。 通常可以在此方法内确认在当前用户会话结束后仍然有效的任何更改(因为用户可能不会返回)。

7.onDestroyView() Fragment中的布局被移除时调用。

8.onDetach() Fragment和Activity解除关联的时候调用。 但需要注一点是:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现。

怎么使用 分为两种 一种是 静态用法 一种是动态用法

静态用法:1.继承Fragment,重写oncreateView 决定Fragment 的布局
2.在Activity 中声明次Fragment,就当普通的View 视图是一样的
动态用法:1.获取到FragmentManager,在Activity中可以通过getFragmentManager 得到,
2.开启一个事务,通过调用benginTransaction 方法开启。
3.向容器内加入Fragment,一般使用replace 方法实现,需要传入容器的id 和Fragment的实例
4.提交事务,调用commit方法提交

fragment启动的生命周期
01-09 1:05:54.608 11678-11678/I/TAG: onAttach
01-09 1:05:54.608 11678-11678/I/TAG: onCreate
01-09 1:05:54.608 11678-11678/I/TAG: onCreateView
01-09 1:05:54.617 11678-11678/I/TAG: onViewCreated
01-09 1:05:54.618 11678-11678/I/TAG: onActivityCreated
01-09 1:05:54.619 11678-11678/I/TAG: onStart
01-09 1:05:54.619 11678-11678/I/TAG: onResume

Fragment竖屏旋转到横屏(横屏旋转回竖屏也是执行同样的生命周期)
01-09 1:05:44.243 11678-11678/I/TAG: onPause
01-09 1:05:44.260 11678-11678/I/TAG: onStop
01-09 1:05:44.266 11678-11678/I/TAG: onDestroyView
01-09 1:05:44.267 11678-11678/I/TAG: onDestroy
01-09 1:05:44.267 11678-11678/I/TAG: onDetach
01-09 1:05:44.325 11678-11678/I/TAG: onAttach
01-09 1:05:44.326 11678-11678/I/TAG: onCreate
01-09 1:05:44.326 11678-11678/I/TAG: onCreateView
01-09 1:05:44.328 11678-11678/I/TAG: onViewCreated
01-09 1:05:44.330 11678-11678/I/TAG: onActivityCreated
01-09 1:05:44.330 11678-11678/I/TAG: onStart
01-09 1:05:44.330 11678-11678/I/TAG: onResume

Fragment退出
01-09 1:15:09.033 11678-11678/I/TAG: onPause
01-09 1:15:09.721 11678-11678/I/TAG: onStop
01-09 1:15:09.721 11678-11678/I/TAG: onDestroyView
01-09 1:15:09.721 11678-11678/I/TAG: onDestroy
01-09 1:15:09.721 11678-11678/I/TAG: onDetach

日常横竖屏切换问题及解决方案
横竖屏切换,导致Activity会重新启动(生命周期流程:onPause()、onStop()、onDestroy()、onCreate()、onStart()、onResume())
1、Dialog
Dialog导致内存溢出、WindowTokenException等等
解决方案:DialogFragment替换Dialog.
2、Activity
Activity重建导致数据问题
1、Activity执行生命周期,先onPuase() —> onStop() —> onDestroy() —> onCreate() —> onStart() —> onResume()
2、如果在这些生命周期中,操作了某些数据,比如在onCreate中添加一条信息“Name”,当横竖屏切换时,又执行了onCreate()这就导致信息“Name”被重复添加的,在数据集中重复出现,进而导致了数据的错乱现象。
解决方案:
1、设置Activity横竖屏时不执行生命周期的方法:
2、或则:在Activity销毁时进行数据的及时的销毁处理。
3、Fragment
1、Fragment重建,系统将会调用 无参构造方法进行重建。
解决方案:
1、参数数据,通过Bundle传递;不要创建其他有参的构造方法
2、默认保留一个公共的无参的构造方法(必须是公共的、无参的。PS:个人有次为了所谓的增强Fragment的封装性,只想对外部抛出newInstance()创建对象的方法,避免使用者调用无参的构造方法出现忘记传值的问题,私自将 public SettingFragment 改为:private SettingFragment;由此导致Fragment的重创建时(例如:横竖屏切换),导致无法初始化Fragment而终止运行,查其原因:系统在横竖屏切换时进行实例化Fragment对象时,调用的是无参的构造方法,而如果设置为私有的则会导致系统调用无参构造方法失败,进而导致实例化失败)。

猜你喜欢

转载自blog.csdn.net/weixin_43564787/article/details/86127735