美文网首页Android收藏集Android组件化Android组件化
组件化开发+MVP框架+Rxjava2+Rxlifecycle2

组件化开发+MVP框架+Rxjava2+Rxlifecycle2

作者: 我做高富帅 | 来源:发表于2018-05-05 17:09 被阅读1318次

前言

应公司需求,重构项目,特搭建一套适合自己公司项目的框架


一.所需掌握的技能点

A.组件化开发:

你需要了解以下知识点

1.gradle基础    
2.注解生成器(apt)
3.注解的使用
3.路由器(本项目使用的是阿里开源的arouter)
4.思维导图工具的使用(目的:是用来分离项目的业务)

B.MVP框架:

你需要了解以下知识点

1.注解的使用
2.泛型的使用    
3.动态代理设计模式
4.抽象工厂设计模式
5.单列设计模式
6.mvp设计思想,简单框架的搭建

C.网络框架:

你需要了解以下知识点

1.rxjava,rxandroid,rxlifecycle,rxpermissions(rx系列基本使用)
2.rxjava的操作符compose,等等。。
2.okhttp使用,栏截器,加密等
3.retrofit 基本使用,与rxjava配合的使用

ok,如果以上知识点差不多掌握那么这套框架你分分钟搞定。写这篇文章主要目的,一是为了记录自己所学知识,二是为了巩固自己。如有写的不好的地方,请各位朋友多多海涵。


二.搭建框架时遇到的问题:

A组件化遇到的问题

1.组件开发时,我需要什么环境
2.组件之间AndroidManifest合并问题
3.各module如何通信(如:activity,fragment)
4.retrofit,api接口怎么定义?

B MVP框架搭建遇到的问题

1.presenter层如何拿到view的引用 ,当view层销毁时产生内存泄漏,如何解决
2.view 为空时,p层怎么处理
3.使用动态代理生成P层,在view层如何用注解拿到p层

C 网络框架搭建遇到的问题

1.封装retrofit时,okhttp,如果封装公共参数
2.如果动态生成api接口类
3.如果封装rxjava的Observable
4.rxlifecycle绑定



进入正题


三.组件化

参考文章:https://blog.csdn.net/guiying712/article/details/55213884#1%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E9%A1%B9%E7%9B%AE%E7%BB%84%E4%BB%B6%E5%8C%96

我们再来回顾下问题

1.组件开发时,我需要什么环境
2.组件之间AndroidManifest合并问题
3.各module如何通信(如:activity,fragment)
4.retrofit,api接口怎么定义?

1.组件开发时,我需要什么环境

组件开发环境主要是利用:组件模式和集成模式的转换

apply plugin: ‘com.android.application’这个是application属性,可以独立运行的Android程序,也就是我们的APP

apply plugin: ‘com.android.library’library属性,不可以独立运行,一般是Android程序依赖的库文件;

odule的属性是在每个组件的 build.gradle 文件中配置的,当我们在组件模式开发时,业务组件应处于application属性,这时的业务组件就是一个 Android App,可以独立开发和调试;而当我们转换到集成模式开发时,业务组件应该处于 library 属性,这样才能被我们的“app壳工程”所依赖,组成一个具有完整功能的APP;

但是我们如何让组件在这两种模式之间自动转换呢?总不能每次需要转换模式的时候去每个业务组件的 Gralde 文件中去手动把 Application 改成 library 吧?如果我们的项目只有两三个组件那么这个办法肯定是可行的,手动去改一遍也用不了多久,但是在大型项目中我们可能会有十几个业务组件,再去手动改一遍必定费时费力,这时候就需要程序员发挥下懒的本质了。

试想,我们经常在写代码的时候定义静态常量,那么定义静态常量的目的什么呢?当一个常量需要被好几处代码引用的时候,把这个常量定义为静态常量的好处是当这个常量的值需要改变时我们只需要改变静态常量的值,其他引用了这个静态常量的地方都会被改变,做到了一次改变,到处生效;根据这个思想,那么我们就可以在我们的代码中的某处定义一个决定业务组件属性的常量,然后让所有业务组件的build.gradle都引用这个常量,这样当我们改变了常量值的时候,所有引用了这个常量值的业务组件就会根据值的变化改变自己的属性;可是问题来了?静态常量是用Java代码定义的,而改变组件属性是需要在Gradle中定义的,Gradle能做到吗?

Gradle自动构建工具有一个重要属性,可以帮助我们完成这个事情。每当我们用AndroidStudio创建一个Android项目后,就会在项目的根目录中生成一个文件 gradle.properties,我们将使用这个文件的一个重要属性:在Android项目中的任何一个build.gradle文件中都可以把gradle.properties中的常量读取出来;那么我们在上面提到解决办法就有了实际行动的方法,首先我们在gradle.properties中定义一个常量值 isModule(是否是组件开发模式,true为是,false为否):

每次更改“isModule”的值后,需要点击 "Sync Project" 按钮
isModule=false

然后我们在业务组件的build.gradle中读取 isModule,但是 gradle.properties 还有一个重要属性: gradle.properties 中的数据类型都是String类型,使用其他数据类型需要自行转换;也就是说我们读到 isModule 是个String类型的值,而我们需要的是Boolean值,代码如下:

if (isModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}

这样我们第一个问题就解决了,当然了 每次改变isModule的值后,都要同步项目才能生效;

2.组件之间AndroidManifest合并问题

在 AndroidStudio 中每一个组件都会有对应的 AndroidManifest.xml,用于声明需要的权限、Application、Activity、Service、Broadcast等,当项目处于组件模式时,业务组件的 AndroidManifest.xml 应该具有一个 Android APP 所具有的的所有属性,尤其是声明 Application 和要 launch的Activity,但是当项目处于集成模式的时候,每一个业务组件的 AndroidManifest.xml 都要合并到“app壳工程”中,要是每一个业务组件都有自己的 Application 和 launch的Activity,那么合并的时候肯定会冲突,试想一个APP怎么可能会有多个 Application 和 launch 的Activity呢?

但是大家应该注意到这个问题是在组件开发模式和集成开发模式之间转换引起的问题,而在上一节中我们已经解决了组件模式和集成模式转换的问题,另外大家应该都经历过将 Android 项目从 Eclipse 切换到 AndroidStudio 的过程,由于 Android 项目在 Eclipse 和 AndroidStudio开发时 AndroidManifest.xml 文件的位置是不一样的,我们需要在build.gradle 中指定下 AndroidManifest.xml 的位置,AndroidStudio 才能读取到 AndroidManifest.xml,这样解决办法也就有了,我们可以为组件开发模式下的业务组件再创建一个 AndroidManifest.xml,然后根据isModule指定AndroidManifest.xml的文件路径,让业务组件在集成模式和组件模式下使用不同的AndroidManifest.xml,这样表单冲突的问题就可以规避了。


image.png

上图是组件化项目中一个标准的业务组件目录结构,首先我们在main文件夹下创建一个module文件夹用于存放组件开发模式下业务组件的 AndroidManifest.xml,而 AndroidStudio 生成的 AndroidManifest.xml 则依然保留,并用于集成开发模式下业务组件的表单;然后我们需要在业务组件的 build.gradle 中指定表单的路径,代码如下:

 sourceSets {
    main {
        if (isModule.toBoolean()) {
            manifest.srcFile 'src/main/module/AndroidManifest.xml'
        } else {
            manifest.srcFile 'src/main/AndroidManifest.xml'
        }
    }
  }

这样在不同的开发模式下就会读取到不同的 AndroidManifest.xml ,然后我们需要修改这两个表单的内容以为我们不同的开发模式服务。

首先是集成开发模式下的 AndroidManifest.xml,前面我们说过集成模式下,业务组件的表单是绝对不能拥有自己的 Application 和 launch 的 Activity的,也不能声明APP名称、图标等属性,总之app壳工程有的属性,业务组件都不能有,下面是一份标准的集成开发模式下业务组件的 AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.guiying.girls">

<application android:theme="@style/AppTheme">
    <activity
        android:name=".main.GirlsActivity"
        android:screenOrientation="portrait" />
    <activity
        android:name=".girl.GirlActivity"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme.NoActionBar" />
</application>

</manifest>

我在这个表单中只声明了应用的主题,而且这个主题还是跟app壳工程中的主题是一致的,都引用了common组件中的资源文件,在这里声明主题是为了方便这个业务组件中有使用默认主题的Activity时就不用再给Activity单独声明theme了。

然后是组件开发模式下的表单文件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.guiying.girls">

<application
    android:name="debug.GirlsApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/girls_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".main.GirlsActivity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".girl.GirlActivity"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme.NoActionBar" />
</application>

</manifest>

组件模式下的业务组件表单就是一个Android项目普通的AndroidManifest.xml,这里就不在过多介绍了。

3.各module如何通信(如:activity,fragment)

在组件化开发的时候,组件之间是没有依赖关系,我们不能在使用显示调用来跳转页面了,因为我们组件化的目的之一就是解决模块间的强依赖问题,假如现在要从A业务组件跳转到业务B组件,并且要携带参数跳转,这时候怎么办呢?而且组件这么多怎么管理也是个问题,这时候就需要引入“路由”的概念了.

在这里我就不做过多介绍了,介绍一个阿里的开源框架:ARouter
各位看官请自行去github查看,这里给张飞机票:https://github.com/alibaba/ARouter

4.retrofit,api接口怎么定义?

请求网络基本每个模块都需要用到,但各个模块都不相互依赖,这时,我们的api接口怎么定义呢
不多说直接上代码

image.png
image.png
image.png

来我们看最后一张图,这里我们传入了一个class<T>这个是用来干嘛的呢,还是不费话直接上代码
A模块下:


image.png

B模块下


image.png
这样就OK了

由于 时间关系就先写到这样,后期有时间再更新。。。

相关文章

网友评论

本文标题:组件化开发+MVP框架+Rxjava2+Rxlifecycle2

本文链接:https://www.haomeiwen.com/subject/pdpdlftx.html