对App应用架构搭建的一些思考

 

当下随着App开发技术的越来越成熟,多人协同开发必不可少,一个团队中每个人的代码风格、技术栈都存在差异,因此统一一套成熟的开发架构必不可少,可以提高开发效率、统一代码风格、为项目维护提供便利。

源码工程结构:

 当下App源码工程通常采用组件化结构,将一个工程拆分为公共基础组件、业务功能库组件、业务数据组件、业务逻辑组件。

 

在CommonModel公共基础组件里面,依赖一些通用工具,如:图片加载库Glide、日志库Log、常用工具类utilcodex、简单的数据存储mmkv、下拉刷新SmartRefreshLayout、recycleview适配器baseQuickAdapter、路由库Arouter、lifecycle、ktx、jetpack组件等,需要所有的业务逻辑模块对其进行依赖,提供给各个业务逻辑模块使用,避免各个模块重复依赖,也利于第三方库的管理。

其它的业务专用功能库,如视频库(视频取流、解码、转码等)、支付库(支付宝、微信等)提供给特定的业务模块,只有相应的业务模块依赖。

业务数据Model是将对应的业务数据接口进行封装,一般包含网络http(s)接口、websocket、socket、ftp、database等需要与远程后端或本地数据进行数据方面操作强相关逻辑的封装。如登录功能,使用将登录接口进行封装,在数据模块定义登录接口,接受用户名、密码等通过网络发送给后端进行验证,处理返回结果,将结果回调给逻辑模块。

业务逻辑Component是负责与用户进行交互的上层逻辑,如视频模块包含的预览、回放界面、对业务数据模块调用获取数据,展示数据等逻辑,一般情况下各个业务模块相互独立,不存在依赖关系。

App壳工程,不包含任何业务相关的逻辑,依赖所有业务模块,是整个程序的入口。

 

以上是对整个工程结构的一些思考,那么通常情况下,各个业务模块是需要进行通信的,并非完全不相关的,比如业务A中有个地方需要携带一些数据跳转到业务B界面进行展示,这就涉及到组件间通信了。

 

组件间通信:

业务组件间通信通常包含界面跳转、数据交换等,由于没有依赖关系,不能直接调用。

那么都有哪些解决办法呢?

1、  采用第三路由框架

比较出名的是Arouter,

ARouter是阿里巴巴开源的路由框架:https://github.com/alibaba/ARouter

  要使用这套框架,需要在各个需要通信的业务模块中添加依赖,配置注解处理器,在Application中初始化Arouter,然后在需要调转的Activity上配置注解即可。

例如:

需要跳转的VideoActivity在业务A模块中

在业务模块B中跳转到业务A模块:

 

 除了简单的Activity跳转外,Arouter还支持Fragment实例的获取、跨组件Api调用等。

 那么Arouter的实现原理是什么?又有哪些优缺点呢?

其实对于路由的原理,实现思路,大都类似,使用过flutter的同学,会知道在flutter中实现widget之间的跳转,需要调用

Navigator.of(context).pushNamed(Routes.SD_DEVICES,

arguments: {"deviceId": "6D05C92YAG8AF53"});

这里的常量Routes.SD_DEVICES,就是我们需要存储在一个Map集合里面,它对应一个Widget,路由框架会依据Routes.SD_DEVICES

 ,找到对应的界面进行跳转。

其实,Arouter的Activity跳转也是类似的,他会将地址和界面存放在一个Map里面,当我们调用跳转代码时,只需传递地址即可找到对应的界面。

 

 

2、  自己实现一套框架

 

 如果我们的项目团队比较大,对路由框架的安全性、可修改性、兼容性等方面都有着更高的要求时,我们可以自己考虑实现一套路由框架。

有什么实现思路呢?

有反射经验的同学,可能就会觉得,对于这种Activity的跳转、方法调用,只需要知道类名、方法名,可以很简单的拿到它们的实例

如:

val clazz=Class.forName("android.app.Activity")
clazz.let{ 
    startActivity(Intent(context,it))
  }
val method=clazz..getDeclaredMethod("getxx",Int::class.java...)
method.invoke(instance,x...)

可以看到反射可以很轻松的实现跨组件通信,但实际开发中我们并不会将反射应用于路由框架中,因为我们的代码一般需要混淆,类名方法名大都会改变,

这时候反射就会失效,另外反射还存在性能问题。

 

这里提供一种思路,我们知道反射作用于运行时,而aop则可作用于编译时,我们在源码中使用注解标记一些方法,在编译时使用注解处理器读取注解,

使用aop框架,把这些代码修改,使各个方法串通

在业务模块A中,需要调用业务模块B中的一个方法并返回一个Fragment,

 

//需要被调用的方法在模块B中

 

fun   getFragmentFromB(...):Fragment {... }

 

代码结构模式MVC、MVP、MVVM:

 

 

posted @ 2020-11-19 20:10  Android开发8585  阅读(435)  评论(0编辑  收藏  举报