当前位置:   article > 正文

《组件化架构》知识汇总_组件式架构是什么意思

组件式架构是什么意思

组件:指单一的功能组件,如视频组件(VideoSDK)、支付组件(PaySDK)、路由组件(Router),每个组件都能单独抽出来制作成SDK,也有的公司内部叫Lib组件

模块:指的是独立的业务模块,如直播模块(LiveModule)、首页模块(HomeModule)、即时通信模块(IMModule)等。模块相对于组件来说粒度更大,模块可能包含多种不同的组件。有的公司内部也叫UI组件

组件化的好处:

  1. 避免重复造轮子,节省开发和维护成本

  2. 通过组件和模块为业务基准合理安排人力,提高开发效率

  3. 不同的项目可以共用一个组件或者模块,确保整体技术方案的统一性

  4. 为未来插件化共用一套底层模型做准备

模块化的好处

  1. 业务模块解耦,业务一直更加简单

  2. 多团队或者团队内多人根据业务内容进行并行开发和测试

  3. 单个业务可以单独编译和打包,加快编译速度

  4. 多个APP共用模块,降低了研发和维护成本(eg:同程旅行,同程旅行极速版)

组件化是功能导向的,模块化是业务导向的

总结一句话:组件化是为了重用而拆分模块,模块化是为了业务分离而拆分模块

shareUid,拥有同一个uer id的多个APP可以配置成运行在同一个进程中,所以默认可以互相访问任意数据,比如prefs,且只有在主module里面声明shareUserId,才会最终打包到full文件夹西面的AndroidManifest中!

Application比Acitivity更先创建,重写refisterActicityLifeCycleCallbacks方法可以拿到栈顶的Activity,而且是全局的。



组件间通信方式

  1. LocalBroadcast(APP内部通信)

  2. EventBus(订阅者、发布者、订阅时间、事件总线)Publisher post(Event),Subscriber onEvent,EventBus3.0+用编译时注解替代了2.x的运行时注解,速度快效率高

  3. RxBus是一种响应式编程的模式,而非EventBus的观察者、监听者设计模式

组件间跳转

  1. 隐式启动Activity,通过sendintent.resolveActivity(getPackageManager!=null安全的跳转,设置exported=false确保其他APP无法跳转到我们的APP中

  2. Router

ARouter:

通过加载编译时注解创建的Group、Providers、Root三个类型的文件,使用WareHouse将文件保存到三个不同的HashMap对象中,而这个WareHouse就相当于路由表。

加载过程:

  1. 通过ARouter.navigation封装postcard对象

  2. tongguo 索引传递到路由中转站,询问是否存在跳转的对象

  3. 如果存在则设置绿色通道开关

  4. 判断是否绿色同行和是否能通过拦截服务

  5. 全部通过就会调用startActivity()

路由最大的好处:

组件间跳转

拦截过滤,登录状态验证等

具体的路由拦截:

路由跳转到需要申请权限的组件或者Activity,则可以实现IInterceptor接口,并重写process()判断postcard.getPath.==("/takePhoto/xxx")则调用权限申请;除此之外还可以登录前、支付前验证,拦截机机制是安全的象征。

反射

获取Class对象的方式:

  1. Class c1 = Class.forName("com.ly.TestA");会装载并进行类的初始化static代码块之类的会走

  2. Class c2 = TestA.class 不会进行初始化

  3. Class c3 = TestA().getClass()会实例化所以static、无参构造都会被调用

Field f = c1.getDeclaredField("name");//可以获取所有属性,包括private的,但是无法获取父类的属性,不过可以通过c1.getSupperClass继续获取父类所有属性。

f.setAccessible(true)取消私有字段的访问限制,public的accessible也是false。

为了安全不管是否是私有属性,全部设置访问权限为true

类型擦除,如果反射的方法的参数的T泛型,则需要用Object.class作为参数。

动态代理,可以在不修改源码的情况下,在方法执行前后做任何事情。

反射框架jOOR

组件化权限:

normal级别的权限申请都放在base module里面,然后各个module中分别申请dangerous权限,这样分配的好处是当添加或者移除单一模块时,隐私权限申请也会跟随移除,做到最大程度的权限解耦。如果权限全部转交到每个module中是可以达到最大程度的权限解耦,但是这样会增加AndroidManifest合并检测的耗时。建议在base module中封装权限申请。

app module中的R文件有final修饰,而lib module中的R文件没有final修饰???

ButterKnife通过gradleplugin构建生成R2文件,目录和R文件一致:build/generated/source/r/debug/xxx/

查看依赖关系命令:

  1. //壳工程:
  2. ​​​​​​​./gradlew :app:dependencies --configuration developerDebugRuntimeClasspath >> dependency.txt
  3. //某个组件
  4. ./gradlew du_publish:dependencies --configuration releaseRuntimeClasspath >> dependency.txt

(如果是别人的项目可能会遇到 bash: ./gradlew: Permission denied)

解决方法: chmod +x gradlew

依赖标注了*号,表示这个依赖被忽略了,这是因为其他顶级依赖也依赖于这个传递的依赖比如:

组件化资源名的冲突解决:

  1. 不同module资源命名不一样

  2. android{resourcePrefix "组件名_"}加上前缀,但是只限定于XML,图片资源依旧需要手动修改

混淆:

混淆包括代码压缩、代码混淆、资源压缩等优化过程。

AS使用ProGuard进行混淆,ProGuard是一个压缩、优化和混淆Java字节码文件的工具,可以删除无用的类、字段、方法、属性、无用资源减少APK大小。

混淆具体有四项工作:

  1. Shrinking(压缩)

  2. Optimization(优化)

  3. Obfuscation(混淆)

  4. Preverfication(预校验)



Gradle的生命周期分为三个阶段:

  1. setting.gradle(初始化)根据include信息决定哪些工程会加入构建过程。

  2. build.gralde(配置)配置阶段会按引用数去执行所有工程的build.gradle脚本,配置project对象,一个对象由多个任务组成,此阶段也会去创建、配置Task及相关信息。

  3. Gradle构建,运行阶段会根据Gradle命令传递过来的Task名称,执行相关依赖任务。

两点问题 一个是混淆

另一个是

Submodule test

SubTree test



Gradle的编译步骤:

代码编译--->代码合成--->资源打包--->签名和对齐

Instant Run的运行原理:

Instant Run 的源码可以通过jd-gui反编译获得

优化gradle编译时间的相关配置(效果未知)

  1. org.gradle.parallel=true(开启并行编译)

  2. android.enableBuildCache=true(使用编译缓存)

  3. org.gradle.daemon=true(减少加载JVM和classes的时间)

  4. org.gradle.configureondemand=true(在大型多项目中更快构建)

  5. org.gradle.jvmargs=-Xmx3072M -XX\:MaxPermSize\=512m(加大编译时的AS内存空间)

为Task耗时添加测量,有针对性的采取优化措施。

task任务过滤(如果没有使用aidl、test、ndk、jni、lint等都可以不运行相关任务)

不执行重复的任务,lib module的Debug/release版本单独依赖。

project不支持Annotation processors的增量build,所以在module种减少使用Annotation processor有助于提升编译速度。



View的生命周期:

你去小卖部,想买瓶可乐,你和店家很熟,自己找到放可乐的位置取一瓶,然后结账。

你去小卖部,想买瓶可乐,你告诉店家你要买可乐,然后他帮你取一瓶,然后结账。

下面的一种就是职责分离,更适合服务客户,此为依赖倒置:

依赖倒置原则是指程序要依赖于抽象接口,不依赖于具体实现,依赖倒置原则的核心是面向接口编程。

加载优化的思路:

核心是时间和空间之间是转换:

  1. 预加载

  2. 线程加载

  3. 懒加载

Java通过Executros提供四种线程池:

  1. newCachedThreadPool(可缓存线程池,如果线程池数量超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程)

  2. newFixedThreadPool(定长线程池,可控制线程最大并发数,超出的线程会在队列中等待)

  3. newSingleThreadPool(单线程的线程池,保证所有任务按照指定顺序执行)

  4. newScheduleThreadPool(定长线程池,支持定时及周期性任务执行)

懒加载:

ViewStub的运行原理:视图加载时,在onMeasure方法中调用setMeasuredDimension传递的参数measureWidth和measureHeight的值为0,draw方法被置空。ViewStub只要被inflate后,会实例化指定的布局,ViewStub的setVisibility()方法被调用时,布局实例化。



gradle的默认缓存地址在Mac上是:/User/用户名/.gradle/caches

那么buildscript中的repositories和allprojects的repositories的作用和区别是什么呢?

答:

1、 buildscript里是gradle脚本执行所需依赖,分别是对应的maven库和插件

2、 allprojects里是项目本身需要的依赖,比如我现在要依赖我自己maven库的toastutils库,那么我应该将maven {url 'https://dl.bintray.com/calvinning/maven'}写在这里,而不是buildscript中,不然找不到。



模板工程路径:

Mac: AndroidStudio/Contents/plugins/android/lib/templates

template.xml:模板填写文件。通过此文件指定添加属性来记录新建模板的要求。

globals.xml.ftl: 模板中记录的全局变量,通过tempalte.xml中的属性可以指定。

recipe.xml.ftl: 模板文件操作逻辑,通过template.xml中的属性可以指定。

FreeMarker的文件后缀是ftl。

FreeMarker类似于MVC设计模式,ftl文件是View层,tempalte是Model数据层,而FreeMarker机制是Controller控制器。

AS头部注释:

Setting/Editor/File and Code Templates----Includes/File Header---Create by ${USER}

模块化:

  1. 应用层:生成APP和加载初始化操作

  2. 模块层:每个模块相当于一个业务,通过module来分割每个业务的逻辑,一个模块由多个不同的页面逻辑组成。

  3. 基础层:基础组件的整合,提供基础组件能力给业务层使用。

  4. 组件层:将图片记在、网络HTTP、Socket等基础功能划分为一层。

  5. 基础库层:更加基础的库类依赖,此层非必须,例如RxJava、EventBus等一些代码结构优化的库,还有自己编写的封装类。

进程化:

进程化是大型APP架构的必然选择,Android系统不是以App为单位分配内存的,而是以进程为单位限制内存和分配资源的。那么开启多个进程会使App获取更多的内存,运行更加流畅。多进程内存分散,既避免了让单个进程太大导致内存过大,在不断回收内存中导致卡顿,也避免了因内存过低被系统杀死。其他进程可以做一些播放视频、播放音乐、拍摄、浏览网页等非常耗费资源的操作。

进程定义需要以四大组件作为入口: AndroidManifest.xml中使用process字段来声明额外进程。

进程化遇到的问题:

  1. 静态成员和单例模式会失效。

  2. 线程同步机制完全失效,由于JAVA同步机制使用虚拟机来进行调度,因为两个进程会有两个虚拟机,同步在多进程中是无效的,sync、volatile等都是基于虚拟机级别的同步。

  3. SP没有对多进程的支持,可以用MMKV

  4. 文件读写、访问同一个文件没有进程锁机制,SQLite很容易被锁,其他进程访问时也会报异常。

  5. Application多次被创建。每个进程在创建时都会新建一个Application,可以通过进程名来区分进程。

类里面logt生成TAG

类似于小程序,多进程,单独的Activity容器

<activity android:name=".MainActivity2"

android:taskAffinity=":remote"

android:launchMode="singleTask"

android:process=":remote"

></activity>


 


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/283948
推荐阅读
相关标签
  

闽ICP备14008679号