每个Android应用启动时,都会先创建一个Application。通常在Application里我们会做一些应用初始化的操作,常见的有第三方SDK初始化。在应用组件化之后,组件与壳工程是隔离开来的,但是组件有时候也需要获取应用的Application,也需要在应用启动时进行初始化。这就涉及到组件的生命周期管理问题。

1. 抽象出一个类似Application的类

首先,我们定义一个类似Application的抽象类出来,它模拟了Application的几个主要方法:public abstract class BaseAppLike {    public static final int MAX_PRIORITY = 10;    public static final int MIN_PRIORITY = 1;    public static final int NORM_PRIORITY = 5;    /**

* 返回组件的优先级,优先级范围为[1-10],10为最高,1为最低,默认优先级是5

*

* @return

*/

public int getPriority() {        return NORM_PRIORITY;

}    /**

* 应用初始化

*

* @param context

*/

public abstract void onCreate(Context context);    public abstract void onTerminate();

}

2. 组件内继承实现BaseAppLike类

在组件内实现一个继承BaseAppLike的类,我们把这个类当做是组件的Application容器。这里的onCreate()等同于Application的onCreate()方法,组件可以在这里获取Application实例、执行启动初始化等操作,也可以在这里设置保存一些全局性的数据等。

3. 怎么管理组件的生命周期

假设我们有组件ModuleA、ModuleB、ModuleC,这3个组件内分别有ModuleAAppLike、ModuleBAppLike、ModuleCAppLike,那么我们在壳工程集成时,怎么去组装他们呢。最简单的办法是,在壳工程的Application.onCreate()方法里执行:@Overridepublic void onCreate() {    super.onCreate();

ModuleAAppLike moduleA = new ModuleAAppLike();

ModuleBAppLike moduleB = new ModuleBAppLike();

ModuleCAppLike moduleC = new ModuleCAppLike();

moduleA.onCreate(this);

moduleB.onCreate(this);

moduleC.onCreate(this);

}

有多少个组件,就得手动构造多少个BaseAppLike,并执行它的onCreate()方法。看起来貌似很简单,根本没什么技术含量,但是实际运用时,你会发现很多问题,接下来讲讲我碰到的问题。

3.1 组件初始化的先后顺序

前面介绍过,上层业务组件是依赖下层业务组件的,如果下层组件在应用启动时也需要初始化,那么我们在加载组件时,必然要先加载下层组件,否则加载上层组件时可能会出现问题。但是组件这么多,我们怎么确定要先加载谁后加载谁呢,当然你可以手动维护,代码里写死,但是当业务越来越多、时间越来越久,肯定不灵活,你新加一个业务组件进来,你都需要确定组件初始化先后顺序。所以,我们必须有个机制来确定组件初始化先后顺序。

类似线程优先级一样, 为每个组件定义了一个优先级,通过重写getPriority()方法可以设置组件的优先级。优先级范围从[1-10],默认优先级都为5,下层组件或需要先初始化的组件,优先级设置高一点。这样我们在加载组件的时候,先对所有组件的优先级进行排序,优先级高的排前面,然后再按顺序进行加载组件,就可解决这个问题了。

3.2 自动加载

前面这个示例,需要在壳工程代码里,手动构建各个组件的BaseAppLike类。这样问题又来了,如果很多个组件都有实现该类,那在集成时得一个一个找出这些类,并且新增加一个组件,你都有可能要去修改壳工程代码,这样显然是不灵活且不利于代码维护的。如果能自动读取并加载这些BaseAppLike类,那显然是极好的,这里有2种方式来实现:在配置文件里定义

在壳工程的assets里放一个json配置文件,定义了所有组件里BaseAppLike类的全路径类名,应用启动时读取该配置文件,通过反射去加载并初始化组件。这种方式只需要修改配置文件即可,实现起来比较简单,但是还是不够灵活。

通过注解配合APT来实现

APT是一种处理注解的工具,它对源代码文件进行检测并找出其中的Annotation,使用Annotation进行额外的处理。所以可以考虑通过注解来标识所有组件内的BaseAppLike类,编译时通过APT提取出来,这样就可以做到自动识别并加载了。

4. 小结

BaseAppLike类的设计目标,首先是为了将整个应用的初始化动作分散到各个子组件内部,子组件对外屏蔽内部实现细节,方便组件的集成使用;其次是在每个组件内部模拟Application类,以方便组件对Application的依赖使用。

作者:云飞扬1

链接:https://www.jianshu.com/p/65433846d38a

android组件化数据生命周期,Android组件化开发实践(五):组件生命周期管理相关推荐

  1. neo4j图数据库:结构化数据流水线、非结构化数据流水线

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 智能对话系统:Unit对话API 在线聊天的总体架构与工具介绍 ...

  2. 数据科学 IPython 笔记本 9.11 结构化数据:NumPy 的结构化数组

    9.11 结构化数据:NumPy 的结构化数组 本节是<Python 数据科学手册>(Python Data Science Handbook)的摘录. 译者:飞龙 协议:CC BY-NC ...

  3. html文档半结构化数据,什么是半结构化数据(semi-structured data)?

    半结构化数据的定义 我们在设计一个信息系统时必然涉及到数据的存储,而数据存储用得最多的就是关系数据库.通常我们会将数据按业务分类,并设计相应的表,然后将对应的信息保存到相应的表中.比如一个企业信息管理 ...

  4. 结构化数据(structured),半结构化数据(semi-structured),非结构化数据(unstructured)

    研究一下分布式架构的实现方式 结构化数据(structured),半结构化数据(semi-structured),非结构化数据(unstructured) 概念 结构化数据:即行数据,存储在数据库里, ...

  5. 结构化数据(structured),半结构化数据(semi-structured),非结构化数据(unstructured)...

    概念 结构化数据:即行数据,存储在数据库里,可以用二维表结构来逻辑表达实现的数据. 半结构化数据:介于完全结构化数据(如关系型数据库.面向对象数据库中的数据)和完全无结构的数据(如声音.图像文件等)之 ...

  6. android用于查询数据的方法,android: SQLite查询数据

    掌握了查询数据的方法之后,你也就将数据库的 CRUD 操 作全部学完了.不过千万不要因此而放松,因为查询数据也是在 CRUD 中最复杂的一种 操作. 我们都知道 SQL 的全称是 Structured ...

  7. Vue——05-02组件的数据、为什么data要使用函数、父组件给子组件传递数据的三种写法、父传子以及传两种以上的值、默认值以及父传子的引用类型

    目录 在组件中获取数据 二.组件中的data为什么必须要是函数? 父组件给子组件传递数据--props属性 第一种写法: 第二种写法: 第三种写法: 传默认值 : 父组件传子组件数据--引用类型的两种 ...

  8. seo结构化数据_为什么使用结构化数据有助于您网站的SEO

    seo结构化数据 Few things are as exciting for a new developer as getting their first customers. The idea o ...

  9. html属于非结构化数据吗,什么是结构化数据非结构化数据和半结构化数据

    什么是结构化数据非结构化数据和半结构化数据以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 结构化数据也称为行数据,是由二 ...

  10. html文档半结构化数据,什么是半结构化数据?

    要考虑半结构化数据是什么,让我们从类比开始 – 采访. 假设您正在进行半结构化访谈.顾名思义,这在介于结构化和非结构化的访谈之间. 对于上下文,结构化访谈是指您的人力资源团队预先确定所询问的问题以及询 ...

最新文章

  1. Ubuntu16.04运行.run文件
  2. Linux文件与目录的rwx权限
  3. OpenGL 加载模型Model
  4. cursor_sharing='SIMILAR'将被废弃
  5. 1月24日学习内容整理:Django的admin组件源码分析及流程
  6. Fedora进入超级用户的方法
  7. Java系统中如何拆分同步和异步
  8. C语言-郝斌笔记-007是否为素数
  9. java对象添加字段_99.9%的Java程序员都说不清的问题:JVM中的对象内存布局?
  10. 数字高程模型|DEM采集的主要方式
  11. Python shift()
  12. 宽带拨号连接失败,代码651
  13. python远程访问服务器获取文件
  14. 【低碳发展案例研究】中国西部中小城市低碳发展研究——以泸州市为例
  15. 研究生带28岁腼腆导师一起相亲?被女生围追堵截要微信!
  16. SAP ABAP OO ALV全屏显示
  17. 深圳神目信息COVID-19抗疫科研成果入选ICMLA2020 oral论文
  18. python底层与机器底层关系_起底 Python 的底层逻辑
  19. 股票期货内盘与外盘以及相关分析
  20. java面向对象编程思想_Java面向对象编程思想的理解

热门文章

  1. python毕业设计项目源码选题(2)新闻管理系统毕业设计毕设作品开题报告开题答辩PPT
  2. html复选框美化插件,Labelauty – jQuery单选框/复选框美化插件
  3. 领导跟跟你说让你多和他沟通,但是你不知道该沟通什么?怎么破?
  4. 三相llc 华为_华为电源常用的3种输入输出方式
  5. 交换排序 java_java排序算法-交换排序
  6. 关于TI毫米波雷达芯片(IWR6843)电源替代方案的探讨
  7. 高数 | 【多元函数微分学 概念篇】连续、可偏导及可微之间的关系
  8. 快捷键+DOS命令+命令提示符
  9. 树莓派GPIO口的常用配置代码
  10. 2022上海市安全员A证考试试题及在线模拟考试