From a347b0f244e2ca67ae91622f619c943b26124e33 Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Wed, 5 Aug 2020 15:10:13 +0800 Subject: [PATCH] =?UTF-8?q?Create=20=E9=A1=B9=E7=9B=AE=E6=80=BB=E7=BB=93.m?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blogs/Android/口水话/项目总结.md | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 blogs/Android/口水话/项目总结.md diff --git a/blogs/Android/口水话/项目总结.md b/blogs/Android/口水话/项目总结.md new file mode 100644 index 0000000..41ce5a5 --- /dev/null +++ b/blogs/Android/口水话/项目总结.md @@ -0,0 +1,41 @@ +--- +项目总结相关口水话 +--- + +#### 目录 + +1. 组件化 + MVP +2. 项目中遇到哪些问题,是怎么解决的? + +#### 项目架构 + +我们项目采用的是组件化 + MVP。 + +模块化大家都知道,new 一个 App Module 即可,组件化不过是模块化更细粒度的表现。我们项目的大致架构是: + +/** 此处该有张图 **/ + +组件化需要解决两个问题,业务模块的划分以及组件间的通信。业务模块的划分是比较麻烦的,因为之前写的都耦合在了一起,目前我们也只有一个发票的模块独立拆分了出来。组件间的通信可以采用 ARouter。ARouter 的源码我倒是没有看过,不过之前也写过路由跳转,核心的思想就是生成一个 Map,Path 对 Activity 的映射。实现方式有两种,第一种是通过元数据的形式,即在 Manifest 注册 Activity 时添加 meta-data 信息,然后在 Application 的 onCreate 时去扫描所有的 Activity 生成 Map,这种方式实现简单,几十行代码就能写完了。第二种方式则是比较传统的通过编译时注解 + JavaPoet 的形式,和 ButterKnife 原理一样。但是写的时候还是发现一些问题的,注解处理器在每个模块下都要引入,生成的类的全限定名是当前的包名 + 类名,里面就一个 public static 的方法,方法里面就是写好的 HashMap 一系列的 put 方法,接下来就是要每个模块生成的 Map 进行合成即可,但是问题来了,在 app 模块是不知道其他模块的名字呀,于是只能在 assets 目录下配一个 json 文件用来读取每个模块的模块名,有了模块名就有了前面生成的类的全限定名了,然后反射执行方法合成 Map 即可。 + +接下来就说说 MVP,MVP 相对于 MVC 来说,完全解耦了 View 层和 Model 层。主流的实现方式是以 Activity 作为 View 层,Presenter 层负责网络请求和数据处理,然后把处理后的数据以接口回调的方式传给 View 显示。 + +然后,就没了 + +#### 遇到哪些问题,是如何解决的? + +##### 输出项目里的权限信息 + +这个在 Gradle Plugin 口水话里面讲过,就不多说了。 + +##### getGlobalVisibleRect + +有一个需求是需要判断一个 TextView 在屏幕内是否可见,然后我就网上搜了一下,发现有一个 getGlobalVisibleRect 这个 Api,它返回的是一个 boolean 值,看了一下文档,可以传一个 Rect 作为参数,之后会拿可见区域的信息给这个 Rect 赋值。起初我是用这个返回值直接判断的,但是后面测试反馈说有 bug,我这测试也没啥问题呀。琢磨了半天才发现,原来顶层布局是一个 ScrollView,ScrollView 会把所有的子 View 一下子全都加载进来,所以这个 getGlobalVisibleRect 会一直返回 true。解决办法就是拿 Rect 的 top 去和屏幕的高判断,如果大于屏幕的高,就说明不在屏幕内,然后测试反馈说有一个小屏手机还是有问题。我去一看,稍微滑动一点,TextView 就显示出来了,我打印了 Rect 的信息,发现真的巧合,它的高度刚好比屏幕的高度高 1 个像素,但是由于 TextView 本身有上边距的影响,导致实际上不可见,然后判断的时候加个 10 像素就行了。 + +##### 构建优化 + +测试有一次反馈打包好慢呀,我试了一下,我们打 debug 包耗时半分钟左右,但是测试在 Jenkins 打 debug 包却接近了两分钟。没得办法,搞一下,之前也参加过 DroidCon 和携程、有赞的关于编译优化的技术分享,拿出来实践一下。最后呢,成果是全量编译由之前的 1m 59s 到 1m 1s,代码增量编译由之前的 27s 到 9s,资源增量由之前的 8s 到 10s。除了资源的逆优化,其他优化效果都非常明显。 + +Gradle 的执行分为三大阶段:Initialization -> Configuration -> Execution 阶段。Initialization 阶段主要目的是初始化构建,它分为两个子过程,一个执行 Init Script,另一个执行 Setting Script。Init Script 会读取全局脚本初始化一些通用的属性,比如 Gradle User Home 目录、Gradle version 等。Setting Script 更常见,它初始化一次构建所参与的所有模块。Configuration 阶段主要影响全量构建的时间,而 Execution 阶段则主要影响增量构建的时间。 + +具体优化措施我在 Gradle 口水话中已经说了,我就不多哔哔了。 +