Android组件化一【赋予Module单独运行的能力】

说到组件化,简直有太多的东西需要了解了,刚入门看别的作者的文章真的能感觉到作者的用心良苦,文章基本都事无巨细的讲解了组件化的原理及流程等。像我这种三分钟热度的人,每次看到那么长的文章看不了几段就看不下去了,太浪费作者的感情。所以我决定还是慢慢看下来,对比下目前的组件化框架,由浅入浅的学习并梳理下组件化的流程。

一、目标

本篇文章的目标就是标题所说的,让module具有单独运行的能力,当然了说的是需要具有该能力的模块,像一些底层的基础模块,其实是没必要实现运行的能力的。这篇文章我们也不讨论跨模块调用的一些问题等,仅仅在于以上所说。

二、准备工作

首先我们准备下基础工程,该工程是一个模块化的工程,包含了app、movie、food、base四个模块,当然app是application模块,其他都是library模块。movie和food依赖base模块,app依赖movie和food模块。
也就是如下模型:

app
movie
food
base

此时的话,我们的movie和food模块都是需要整个打包到app中才可以运行的。当我们只修改了movie或者food模块的时候我们希望只针对这个模块运行,然后调试,这样的话会减少整个编译的时间,所以以此来说效率会提升很多。
工程模块图如下,可以看到只有app模块可以运行:
在这里插入图片描述

三、赋予Module运行的能力

3.1、原理(两种)

我们知道,app模块和其他三个模块明显的不同之处在于build.gradle中的一处配置:

#app模块中:
apply plugin: 'com.android.application'

#其他模块中:
apply plugin: 'com.android.library'

简单点甚至不负责任的说,使用application方式就可以让这个模块具备运行的能力。所以就针对这里我们可以思考下,如果我们直接将movie或者food改为application可以么?当然不可以,这样会将工程打乱,导致我们在运行app模块的时候出现问题。也许你会想到在gradle中进行配置,当单独运行movie或者food模块的时候我们就设置为application方式,当整体打包的时候我们就将movie和food模块设置为library方式。很好,有些框架【例如:CCDDComponentForAndroidJIMU】就是这么做的,也提供给了你很简单的配置方式,你可以轻松实现,下文我们通过集成CC来实现。

然而还有另一种巧妙的做法,那就是我专门给movie或者food模块套一个壳,什么意思?其实我们整个工程就是app壳里包含了movie和food模块,也就是说app同时依赖了movie和food。那假如我专门新建一个application模块比如叫runMovie,让他它只依赖movie模块,这时是不是也达到了让movie模块单独运行的能力呢,只是运行的时候我们得运行runMovie模块,原本的movie模块还是library模块,基本可以不做更改。使用该方式的框架有ComponentAppJoint等,下文我们通过集成AppJoint来实现。

其实就单从我们的目标来说不引入任何框架我们可以自己搞定的,尤其第二种方式更为简单。但是,为了以后学习组件化的其他内容,包括路由以及其他各种跨模块调用等,我们现在需要从这些框架出发,一步步学习,并体验这个过程。
为什么选择这两个框架,因为CC集成文档超详细,因为AppJoint集成超简单。具体的框架选用请大家自行选择,这里不做推荐。

3.2、集成CC步骤

具体文档在:https://qibilly.com/CC-website/#/ ,这里简写下集成的必要步骤,版本号请自行更改:

3.2.1、 在工程根目录的build.gradle中添加cc-register插件的classpath:

buildscript {
    dependencies {
        classpath 'com.billy.android:cc-register:x.x.x' 
    }
}

3.2.2、在工程根目录创建一个名为"cc-settings-2.gradle"的文件,并将以下代码复制到该文件中:

project.apply plugin: 'cc-register'
project.dependencies.add('api', "com.billy.android:cc:x.x.x")

然后Sync项目。
3.2.3、改造movie模块:

  • 将该模块的build.gradle文件中的
apply plugin: 'com.android.library'

修改为:

apply from: rootProject.file('cc-settings-2.gradle')
  • 修改该模块的applicationId
android {
   defaultConfig {
       //仅在以application方式编译时才添加applicationId属性
       if (project.ext.runAsApp) { 
           applicationId 'com.cooloongwu.movie' //ID自己定,但是不能和app模块的ID相同
       }
   }
}
  • 创建使其单独运行必须的文件
    此步骤繁琐,请按照官方文档详细操作,总之保证要有需要的清单文件,入口Activity等文件。
    此时Sync项目后仍旧会报错,我们还需要配置app模块。

3.2.4、app模块的修改

  • 添加如下内容
ext.mainApp = true //标记为主app module
apply from: rootProject.file('cc-settings-2.gradle')
  • 修改依赖movie模块的方式
    将原来依赖movie模块的写法
implementation project(path: ':movie')

修改为

addComponent 'movie'

然后Sync项目后你可以看到movie模块已经可以被选中来运行了。如下两图所示,左图movie模块已经显示了可以运行的标志,在右图中可以选择movie模块运行:
在这里插入图片描述 在这里插入图片描述

3.3、集成AppJoint步骤

3.3.1、在项目根目录的 build.gradle 文件中添加 AppJoint插件 依赖:

buildscript {
    ...
    dependencies {
        ...
        classpath 'io.github.prototypez:app-joint:x.x.x'
    }
}

3.3.2、在主 app 模块应用 AppJoint插件:

apply plugin: 'com.android.application'
apply plugin: 'app-joint'

3.3.3、在主 app 模块和每个需要单独运行的模块添加 AppJoint 依赖:

dependencies {
    ...
    implementation "io.github.prototypez:app-joint-core:{latest_version}"
}

3.3.4、新建壳模块
新建runMovie模块,然后修改其build.gradle文件为application,并依赖movie模块:

apply plugin: 'com.android.application'

implementation project(path: ':movie')

此时runMovie模块已经显示在运行按钮的左侧了,但是现在还处于错误状态,无法运行,如下所示:
在这里插入图片描述
为什么呢?哈哈哈,因为没有配置清单文件和入口Activity呀。同以上3.2.3步骤中的配置类似,当你给该模块配置完清单文件以及入口Activity那么runMovie模块立马就是可以运行的状态了。如下是清单文件必备基本选项:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cooloongwu.runmovie">

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity android:name=".DebugMainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

四、总结

经过以上两种方法,你的movie模块应该已经可以单独跑起来了。其实,现在回过头来我们发现,就算不引入这两个框架我们也可以自己达到这样的目标,从AppJoint的方法中我们更可以清晰的明白,就算我们只做最后一步,加个壳模块,我们已经达到目标了。

但是学完本篇文章对你现在的项目并没有什么作用,充其量只是让你了解了两种让module可以单独运行和调试的方式。CC的方法是使用if-else来判断的方法,修改当前module,通过gradle配置或者gradle插件来帮你运行。AppJoint的方法是加壳的方法,为每一个需要单独运行的module加壳,或者为某几个需要一起调试的module加壳,然后你可以把这些壳模块单独放到一个文件夹中去,也不会特别影响原来项目的结构,这是一个做加法的操作,个人感觉更为优雅一点。

发布了40 篇原创文章 · 获赞 47 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/u010976213/article/details/103097837