【Android组件化】 组件化基础

969 阅读4分钟

组件化是什么

项目开发的时候,我们一般会将公用的代码提取出来封装成基础库 Base module,作为工具类库。然后将实现某些功能的代码封装到功能库 Library module。最后根据业务来划分 module,这样就可以让不同的人开发不同的模块,实现并行开发。 随着以上安排的发展最终我们的项目将演化为多 module 划分业务和基础功能

组件:实现单一功能的 module。如推送组件(PushSDK),支付组件(PaySDK)类似。

模块:独立的业务 module。登陆模块(LoginModule),首页模块(HomeModule)类似。

模块化和组件化都是为了代码的重用和解耦。但是由于每个项目的不同,所以可能会出现已经组件化的 module 在新项目中有部分功能没有使用,造成代码的冗余,随着项目越来越大,造成65535方法数的问题,这时需要选择MultiDex或者使用插件化方式开发项目。

如何实现组件化

Android Studio为我们提供了实现组件化的设计 —— module 依赖。通过依赖我们可以访问被依赖 module 的代码和资源。

如图所示,在项目的Project Structure中,提供了基本的三种依赖方式:

(1)Library dependency:根据设置的仓库来完成仓库索引的依赖。可以设置为网络和本地。

(2)Jar dependency:通过引入libs文件夹中所有的.jar和.aar后缀文件来进行依赖。

(3)Module dependency:使用基础模块库(lib module)作为依赖。实质上也是将其打包为.aar文件进行依赖。

这些操作都会同步到配置的build.gradle文件中。

我们在创建新的 module 时都会生成对应的AndroidManifest.xml文件用于记载模块的信息。而最终合成的APK中只存在一份AndroidManifest.xml,所以Android Studio将多个AndroidManifest.xml合并为一个。一般都是以一个app module 搭配多个业务 module 组成我们的项目。最终生成的目录为app/build/intermediates/manifests/full/debug/AndroidManifest.xml,它记录了所有模块的信息。这个过程包括了资源的汇总和解决冲突。

(1)资源汇总:每个 module 在编译的时候都会在模块的当前目录/build/outputs/aar下生成对应的.aar文件。当编译app module的时候会将其依赖的每个module重新编译,将生成的.aar文件放在app module的app/build/intermediates/exploded-aar文件夹中(因为exploded-aar文件夹在新版AS中添加了缓存,需要在gradle.properties文件中添加android.enableBuildCache = false才能显示)。

其中 class.jar文件是 module 的代码包。可以看到对应的AndroidManifest.xml文件。 (2)资源变更:在每个 module 注册的Activity在汇总的时候会补全包名+文件名。否则会找不到对应的Activity。四大组件都一样。如果 module 中有多个替换了Application,那么替换规则:解决冲突后,app module 的优先级大于功能 module。权限会被汇总到app module中,且不会重复。Activity的主题会引用最后合并的AndroidManifest.xml中声明的主题,要是没有声明,默认使用Android自带的。通过声明相同的sharedUserId的多个APP可以运行在同一个进程中,可以访问各自的数据。只有在app module中声明才会被最终打包到AndroidManifest.xml中。

Application

Application提供了很多有用的回调方法。

(1)onCreate():初始化操作。

(2)onTrimMemory():在系统内存不足,所有后台程序(优先级为background的进程,不是指后台运行的进程)都被杀死时,系统会调用OnLowMemory。

(3)onLowMemory():Android 4.0之后提供的API,系统会根据不同的内存状态来回调。

(4)onConfigurationChanged(Configuration newConfig):当设备的信息改变的时候将会调用,某些时候你需要在系统一些配置信息改变的时候activity避免重新onCreate(),你就可以在android:configChanges声明,某个属性已经声明了,那么在这个属性的信息改变的时候就只会回调onConfigurationChanged(Configuration newConfig)方法。

(5)registerActivityLifecycleCallbacks():APP内所有Activity的生命周期监听。全局Toast可以引用Application的context对象。全局弹框就需要引用此方法回调函数返回的当前窗口对象的顶层的Activity。