一.Activity分发:
在Android开发中,Activity是Android的四大组件之一,作为页面呈现容器,起到与用户交互的关键功能。一个Activity可以看作一个独立的容器,可以容纳非常多的业务。
Activity的生命周期:
- onCreate():在创建启动时调用;
- onStart():处于可见状态时调用;
- onResume():Activity显示在UI顶层时被调用;
- onPause():Activity不再UI顶层,但依然可见;
- onStop():Activity处于不可见状态时调用;
- onDetroy():当Activity推出时调用。
Activity的不同声明周期流程:
- 正常的流程周期:
启动:Activity:onCreate()->onStart()->onResume();
销毁:Activity:onPause()->onStop()->onDetroy()。
- 当Activity被其他Activity覆盖了一部分,或者手机被锁屏时,会被判定为可见状态,但不在UI顶层时,会调用onPause函数。当覆盖部分被去除或者屏幕解锁后,AMS会调用该Activity的onResume方式来再次进入运行状态;
- 当Activity跳转到新的Activity或按Home键回到主屏时,会被压栈,处于不可见状态,会调用onPause()->onStop()。当返回上一个Activity时,系统会调用onRestart()->onStart()->onResume()再次进入运行状态。
- 当Activity处于被覆盖状态或后台不可见状态时,当更高优先级的app需要内存且系统内存不足时被杀死次Activity。当用户退回当前Activity时,会调用onCreate()->onStart()->onResume()进入运行状态。
- 当使用Back键退出Activity时,系统会调用onPause()->onStop()->onDetroy()。
按照业务划分,如activity负责一个整体的大业务,其中有存在很多小业务,那么此activity就可以被分解为不同的module来进行管理,需要关注以下规则:
- 大业务中创建小业务的实体。从module层级来说,大业务需要依赖小业务。大业务将创建出小业务的实体;
- 小业务的生命周期拥有其自身的生命周期。小业务的生命周期需嵌入大业务生命周期中进行传递,但小业务也需要适当调整和管理自身生命周期中的调用规则;
- 小业务的生命周期不应该超过大业务。小业务的生命周期超过大业务的生命周期,将引发内存泄漏;
- 小业务不会依赖于大业务,小业务之间不存在互相依赖。
需要关注分发对象包含的参数:
- (Activity)Context:上下文对象;
- ViewGroup:布局对象;
- saveInstanceState:保存状态的对象。
通过ModuleManager管理这些参数的传递,以及初始化每个业务模块,并且分发生命周期到每个业务模块中。
- 在Base module中使用CWModuleContext来保存Activity分发的三个参数,一个module可以占用多个不同的ViewGroup,而使用SparseArray来保存整个布局的ViewGroup列表(所以Android提供了一个SparseArray类来替代HashMap,SparseArray要比 HashMap 节省内存,某些情况下比HashMap性能更好。SparseArrayCompat是SparseArray 的兼容版本,可以在更低版本的Android运行。我们可以把SparseArray 和 SparseArrayCompat理解为一个东西。):
-
public class CWModuleContext { public Activity mContext; private Bundle saveInstance; private SparseArray<ViewGroup> mViewGroupSparseArray = new SparseArray<>(); }
- ModuleManager管理这些module与activity的关联信息,最关键的是关联module和activity之间的生命周期:
-
public class ModuleManager { private List<String> module = new ArrayList<>(); //模块名字 protected ArrayMap<String,CWAbsExModule> allModules = new ArrayMap<>(); public List<String> getModuleName() { return module; } public void moduleConfig(List<String> modules) { //模块配置信息 this.module = modules; } public CWAbsExModule getModuleByNames(String name){ return allModules.get(name); } public void onResume() { for (CWAbsExModule module : allModules.values()) { if (module != null){ module.onResume(); } } } public void onPause() { for (CWAbsExModule module : allModules.values()) { if (module != null) { module.onPause(); } } } public void onStop() { for (CWAbsExModule module : allModules.values()) { if (module != null) { module.onStop(); } } } public void onConfigurationChanged(Configuration newConfig) { for (CWAbsExModule module : allModules.values()) { if (module != null) { module.onOrientationChanges(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE); } } } public void onDestroy() { for (CWAbsExModule module : allModules.values()) { if (module != null) { module.onDestroy(); } } } }
全部业务模块的实现都需要继承CWAbsModule抽象类:
-
public abstract class CWAbsModule { public abstract boolean init(CWModuleContext moduleContext, Bundle extend); public abstract void onSaveIntanceState(Bundle outState); public abstract void onResume(); public abstract void onPause(); public abstract void onStop(); public abstract void onOrientationChanges(boolean isLandscape); public abstract void onDestroy(); }
-
public abstract class CWAbsExModule extends CWAbsModule { }
- 将ModuleManager扩展成一个ActivityModuleMangager类,用于传递activity的三个参数:
二.Fragment分发:
fragment是嵌套于activity中的一个非常大的业务,拥有自身独立的生命周期。不同业务module也能嵌套到fragment。
Fragment的生命周期:
Fragment的生命周期与Activity的生命周期非常类似,Fragment有其他自身独有的生命周期函数。
Fragment必须依赖一个Activity运行,所以Activity生命周期调用会优化于Fragment,并且Fragment比Activity轻量:
- onAttach是Fragment与Activity建立关联时被调用的函数,用于获取Activity传递的值;
- onDetach是Fragment与Activity的关联被取消时调用的函数;
- onCreatView在创建Fragment视图时调用;
- onActivityCreated在初始化onCreateView方法的视图后返回时调用;
- onDestroyView视图被移除时调用;
Fragment视图的生命周期简要解析:
- Fragment创建时调用:onAttatch->onCreate->onCreateView->onActivityCteated
- Fragment可见时调用:onStart->onResume
- Fragment进入后台不可见状态的时调用:onPause->onStop
- Fragment销毁时调用:onPause->onStop->onDestryView->onDestroy->onDetach
Fragment可以看作需要依赖Activity而存在的一个大业务,但是系统已经为其嵌入好了生命周期,并且Fragment拥有自身栈管理的机制。
在onCreateView函数触发时机是在Fragment布局初始化完成后,可以在onCreateView中初始化moduleManager:
三.View分发:
View有两种构造方法被调用的情况:
1.在View创建时调用;2.在layout文件文件加载被调用。
- onFinishInflate:当View及其子View从XML文件中加载完成后会被调用;
- onAttacheToWindow:当前View被附到一个window上时被调用;
- onMeasure:计算当前View的尺寸及其所有子View的尺寸大小时被调用;
- onSizeChanged:当前View的尺寸变化时被调用;
- onLayout:当前View需要为其子View分配尺寸和位置时被调用;
- onDraw:绘制View呈现的内容时被调用;
- onWindowFocusChanged:当前View的window获取或者失去焦点被调用;
- onDetachedFromWindow:当前View从一个window上分离时被调用。
View被加载时,根据参数会有三种情况:
- View在Visible(可见)时的调用:onAttatcheWindow->onMeasure->onSizeChange->onLayout->onDraw
- View在InVisible(不可见)时的调用:onAttatcheWindow->onMeasure->onSizeChange->onLayout
- View在Gone(加载)时只调用onAttatcheWindow。
- View被销毁时调用:onWindowFoncsChanged->onWindowVisibilityChange->onDetachedFromWindow
Activity和View的生命周期的关联情况:
- Activity在onCreate阶段会使用setContetntView将XML布局文件的控件映射到Activity布局中,此时View会执行构造方法,完成View会执行构造方法,完成初始化后回调onFinishInflate方法;
- 在调用生命周期onResume之后,View会相应调用onMeasure方法来测量自身大小,如果大小发生变化就继续调用onSizeChanged,接着通过onLayout计算放置在布局中的位置,之后调用onDraw来绘制界面,Activity会调用onWindowFocusChanged来改变焦点;
- onPause和onStop会触发onWindowFoncsChanged,告诉外界Activity已经失去焦点;
- 在Activity销毁调用onDestroy时,View会从Activity解绑调用onDetachedFromWindow;
- 异常回收Activity的情况下,保存状态时调用onSaveInstanceState,恢复调用onRestoreInstanceState。View自身也存在这两个对应的函数;
- View也拥有onConfigurationChange函数,用于出发视图配置更新,如横竖屏的转换。