美文网首页
Android组件化开发基本应用

Android组件化开发基本应用

作者: 杰奎琳子 | 来源:发表于2020-09-12 17:04 被阅读0次

    初始模型

    组件化目录结构:

    这里需要注意一下,main组件的gradle文件中,apply plugin使用的是com.android.application

    其他业务模块,使用的是com.android.library

    因为在最终的发布版中,其他业务组件是集成到main组件中的,main组件编译生成最终的application,或者可以这么理解,main组件和app外壳是我们app的必备组成部分,一起构成了可对外发布的完整app,其他组件可以以集成进来,也可以不集成进来,只会增加或者减少我们app的功能,但不影响我们app的最终发布。所以我们在新增module的时候,选择的类型应该是library。

    各个组件都建立完成之后,接下来可以把组件集成到main组件中,集成非常简单,只需在main组件的gradle文件中,添加如下语句

    各组件单独开发

      前面我们把各个组件集成到到main组件,现在我们把组件拆出来,单独开发,开发完后,可以再把组件集成到main中,发布。这是组件化开发的最大亮点(优点)。

      这里我们把home组件单独出来开发。第一步,需要把其library模式改为application模式,因为只有application才可以单独运行,library必须依靠application才能运行。所以,接下来,我们就要在home所对应的gradle文件中做修改。

    修改成

    等要集成到main组件时,又得改回来,如果这样子手工去改,组件一多,修改起来麻烦,也不优雅。优雅的解决办法就是,设置一个开关,打开时,就是application模式,可以单独开发,关闭时,就是library模式,可以集成到main组件中。

      在项目根目录下,有一个gradle.properties文件

    在这文件中,我们可以添加一个常量isDebug,值设为true。

    这里设置了常量之后,我们项目中的其他build.gradle文件都可以把这个常量读取出来,所以我们可以在home的build.gradle文件中,读取该常量的值,动态设置applyplugin

    这样子设置之后,当我们需要切换模式时,只需要修改gradle.properties文件中isDebug的值,修改完成之后,点击Project sync按钮同步一下,如果有报错,那么还有个地方需要修改一下,就是main组件的build.gradle文件,看下图

    为什么做这样的修改?因为我们把module的模式改成了application了,这里不能引入application,引入的话会报错,所以当是debug模式时(也就是组件单独开发时),这里就不引入该组件,免得报错。

      接下来,还得修改 AndroidManifest.xml。因为当我们把一个module设置为application时,其AndroidManifest.xml需要包含一个app所需要的属性,例如app的icon、theme、launch Activity这些属性设置,而当module为library时,上面所提的这些属性都不需要用到,所以当我们处于不同模式时,AndroidManifest.xml文件也得不同。我们在home的src文件夹中新创建一个目录为debug目录,再把我们用于debug时的AndroidManifest.xml文件放进去。由于在Android目录模式下比较难创建这个目录,所以我们可以选另外一种目录模式(Project目录模式),然后再创建debug目录(很绕,直接看下图就会明白了)。

    AndroidManifest.xml文件内容可以这样写

    <?xml version="1.0" encoding="utf-8"?>

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.zhuang.home">

    <application

    android:allowBackup="true"

    android:icon="@mipmap/ic_launcher"

    android:label="@string/app_name"

    android:roundIcon="@mipmap/ic_launcher_round"

    android:supportsRtl="true"

    android:theme="@style/AppTheme">

    </application>

    </manifest>

    以上内容会有很多错误提示,其实提示的无非就是资源找不到,我们只需要把这些资源给加上就好了。可以把main组件中相应的资源拷贝过来,放在对应的目录下就可以了。

      接下来在home组件的build.gradle文件中,指定不同模式下的AndroidManifest.xml文件。

    sourceSets {

    main {

    if (isDebug.toBoolean()) {

    manifest.srcFile 'src/main/AndroidManifest.xml'

    }

    }

    }

    以上设置完成,并且sync project之后,home组件会是这样的目录

      并且android studio的运行app里面,多了一个可运行的app,就是home。

    由于我们home组件集成到main组件中时,是以一个fragment界面集成上去的,所以我们的home组件中,没有一个MainActivity可以作为LaunchActivity,我们可以创建一个,然后把fragment在MainActivity的layout  xml文件中放进去就可以了。

      所对应的activity_main.xml布局文件如下

    <?xml version="1.0" encoding="utf-8"?>

    <fragment xmlns:android="http://schemas.android.com/apk/res/android"

    android:name="com.zhuang.home.HomeMainFragment"

    android:layout_width="match_parent"

    android:layout_height="match_parent">

    </fragment>

    以上步骤完成之后,home就可以单独作为一个app来开发了,我们可以直接运行该组件。

    共用资源的引用

    实际项目中,总有一些资源需要共用,例如第三方库、自定义的工具类、自定义的view等等,甚至我们的theme。那么这些资源在“组件化”中,应该如何处理?每个组件都各自引入?

      如果每个组件都各自引入这些共用资源,一方面效率差,如果一个类是所有组件都用到的,那么就得每个组件中都新增这个类,一旦这个类修改了,还得一个组件一个组件的来修改这个类;另一方面,第三方类库也有可能会冲突,例如不同组件引用了相同的第三方库,但是版本不一样,就冲突了。所以,我们得用另外的方式来处理。

      解决的办法就是,也把共用库组件化,然后其他组件引用它,所以我们的架构可以演化为这样:

    在项目里面把这个共用库加上

      然后可以把其他第三方库、自定义view、工具类、公用资源放进该组件。例如网络请求框架retrofit,在common的build.gradle文件中:

    然后其他组件,都分别引用common组件,在其他组件对应的build.gradle文件中

    这样就可以使用common组件的资源了。

    其实我们还可以更简化,每一个组件的build.gradle所引入的资源,其实有很多是重复的,我们一样可以把这些一并加到common组件中去,例如下面这一段,就是所有组件都有的

    所以这一部分,也可以放到common里面去。所以三大业务组件里面的build.gradle文件就变成这样:

    除了第三方库,还有自定义的工具类、自定义的view等等这些,就直接在common中编写java文件就行啊,其他组件能够引入这些类的。

      还有就是图片、xml这些(value目录下的各种xml文件),也是可以一样被其他组件引用,这里需要特别注意的是style.xml文件,对于全局共用的style,我们应该把它也放在common中。例如我们的项目theme,本来是放在main组件的style里面,我们可以把它移到common中,这样其他组件调试时,作为一个单独的项目,也能和主项目有一样的主题。

      总之就是,所有你认为可以被各个组件共享的资源,都可以放在common组件中。

    资源冲突

    多组件集成时,其资源文件会被归档到一起,所以如果命名重复,那么就会发生冲突,导致界面混乱。为了解决这个问题,我们可以让各个组件中的资源都有一个属于自己的前缀,例如home组件中的资源,我们可以以home_开通,video组件中的资源,我们可以以video_开头,这样就防止了资源冲突。在这里gradle可以帮我们做一点事情,就是让我们在命名资源文件时,帮我们先加上前缀。例如在home组件的build.gradle文件中,加入

    resourcePrefix"home_"

    这样之后我们的xml文件如果没有以home_为前缀的话,就会报错。但是这个功能其实很弱,例如xml文件报错,但是我们运行的时候,依然可以运行,图片文件不已home_为前缀,也不会报错,所以,资源冲突的问题,还需要开发者自己多多注意。

    组件之间的通信

      组件虽然可以拆分了,但是当他们集成到main组件中,一起工作时,还是需要一定的通信,例如业务A需要调用到业务B的一个页面,甚至进行传参。但是在“组件化”模式下,业务A和业务B是完全分开的,在业务A的认知里,根本就不存在业务B,也无从直接调用。当然,如果要A与B可以直接通信,也是可以的,互相引入就可以,但是这样的话,项目耦合性太高,架构也混乱,会把“组件化”的所有优点都一一撇掉。我们应该用另外一个方式来处理。

      这里需要引入一个概念----“路由”,就如我们实际访问网络一样,我们电脑发送的请求都经过路由器转发,在“组件化”中,我们也可以设置这么一个中转站,来统一处理不同组件之间的调用关系。支持我们这一思想有一些比较有名的开源项目,如ARouter、ActivityRouter,通过这些开源项目,我们可以用一个url,由其转发,帮我们调用其他组件。

    ARouter使用:

    参考链接:

    https://mp.weixin.qq.com/s?src=11×tamp=1599552720&ver=2571&signature=msb3wX*txhuX2O57iSYbmyqaE-0QNpTBF3ZNTpEwMhwLIhj0uO9mrZt4KCT4tvT*G9bvLRDzWjkcvrVXBY7r92TlEbV2HNEYuNZRrscIzq4EtP1dvCJAgcjqruNN8Zp4&new=1

    统一版本号

    各个组件的build.gradle文件中,有很多版本号。

    我们可以把这些版本号统一管理起来,免得每次修改都得同时修改多份build.gradle文件,也避免不同的组件使用的版本不一样,导致冲突。

    在项目build.gradle文件中(项目根目录下的build.gradle文件),定义版本号常量

    ext {

    compileSdkVersion = 25

    buildToolsVersion = "25.0.2"

    minSdkVersion = 14

    targetSdkVersion = 25

    versionCode = 1

    versionName = "1.0"

    }

    然后在各个组件的build.gradle文件中,做这样的修改

    相关文章

      网友评论

          本文标题:Android组件化开发基本应用

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