Android 模块化开发

举报
yd_221104950 发表于 2020/12/02 23:52:26 2020/12/02
【摘要】 概述 单独开发每个模块,用集成的方式把他们组合起来,拼出一个app。如通用的模块,自动更新的模块,反馈模块,推送模块都可以单独以模块来开发,最后进行集成。我们可以通过一个壳来包含很多个模块。 好处 可以单独升级模块。耦合度低。同时,也很好地解决了“牵一发而动全身”的问题。方便分工。与其他团队合作时,如外包的团队,可以很好的地将核心代码与外包部分隔离开,不用和他们分...

概述

单独开发每个模块,用集成的方式把他们组合起来,拼出一个app。如通用的模块,自动更新的模块,反馈模块,推送模块都可以单独以模块来开发,最后进行集成。我们可以通过一个壳来包含很多个模块。

好处

可以单独升级模块。耦合度低。同时,也很好地解决了“牵一发而动全身”的问题。方便分工。与其他团队合作时,如外包的团队,可以很好的地将核心代码与外包部分隔离开,不用和他们分享核心代码,让他们去做独立的功能,做好直接调用就行。方便以后重构代码,不用担心会改到核心代码。

架构分层

在这里插入图片描述

  • 顶层
    将所有的业务模块聚合在一起,加上配置,形成主应用。一个模块化做得好的应用,主应用都会比较简单且稳定。
  • 中间层
    模块按照功能划分。比如app可以划分为更新、登录、分享、播放等模块。采用aar作为模块的最小单位,之所以选择aar是因为jar不能带资源只能带java代码,library太容易被修改。aar的好处是能带资源并且是编译好的,不能被修改。保证了模块的版本不会在被别人调用的时候随意修改,如果想修改就要联系做aar的人,让他去升级aar的版本。
    在android studio里,用maven打包aar。aar其实就是依赖。
  • 底层:包含基础库和底层库
    (1)基础库:包含所有模块需要的依赖库,以及一些工具类,比如封装了的常用网络请求,封装图片处理fresco,数据库相关等,还包含所有模块需要的依赖库;
    (2)底层库:主要是使用C/C++开发的跨平台的引擎或者库,以so的形式存在。

Android Studio 项目结构

在这里插入图片描述

  • MyApplication 整个项目目录
  • MyApplication/build.gradle是整个项目的gradle构建脚本
  • MyApplication/gradle.properties是整个项目的gradle设置
  • MyApplication/MyApplication.iml是整个项目的配置文件
  • MyApplication/settings.gradle是定义整个项目包含哪些模块
  • app项目中app模块目录
  • app/build/是app模块build编译输出的目录
  • app/app.iml是app模块的配置文件
  • app/.gitignore是app模块的版本管理忽略文件
  • app/build.gradle是app模块的gradle构建脚本
  • app/proguard-rules.pro是app模块的混淆文件
  • External Libraries 项目依赖的Lib,编译时自动下载的

Android Studio 新建的项目自身就是一个模块化项目。因为MyApplication 是整个项目,而app是一个模块。可以在后续自行增加更多的功能模块。

在Android Studio进行模块化开发

1.创建 Module 模块
有两种方式。
方式一:针对已存在的模块,只需要将模块复制到项目的根目录(如上面的MyApplication目录)下即可。这种方式需要在根目录下的setting.gradle文件中设置一下,格式:

include ':projectName'

  
 
  • 1

方式二:直接在project下新建一个Module。操作步骤:

File --> New --> New Module --> Android Library (建议选择这个) --> Finish

  
 
  • 1

这种方式会自动在根目录下的setting.gradle文件中设置。

如:
在这里插入图片描述

在主模块app模块的build.gradle中设置:

dependencies {
... implementation project(path: ':modulea')
}

  
 
  • 1
  • 2
  • 3
  • 4

模块中 application 和 library 状态切换配置

组件化插件化是两个不同的概念。插件化作用在“运行时”,而组件化作用在“编译时”。插件化是基于多APK,而组件化本质上只有一个APK。
(1)用一个属性来控制gradle构建插件的切换。 如果我们创建的Module是要作为一个库library来给别的模块使用,那么就应该使用com.android.library这个gradle插件来构建。如果我们Module是一个应用,而不是插件,那么就要使用com.android.application这个gradle插件来构建。我们可以在gradle.properties文件(在根目录下)来配置一些属性,然后在各个Module的build.gradle的构建脚本里就可以根据这属性来判断要使用哪个插件,如:
gradle.properties

# false表示是集成化开发模式,true表示是组件化开发模式
isModule = false

  
 
  • 1
  • 2

isModule = false:表示这个模块是一个Module(插件);
isModule = true:表示这个模块是一个app(组件);

(2)在模块的build.gradle文件中使用isModule属性。

在modulea模块的build.gradle中使用isModule来判断要使用哪个构建脚本插件:

if(isModule.toBoolean()){ apply plugin: 'com.android.application'
}else{ apply plugin: 'com.android.library'
}
android {
... defaultConfig {
		... // library下删除applicationId // 如果是组件就要给一个applicationId if(isModule.toBoolean()){ applicationId "com.wong.modulea" } }
...
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

(3)提供两套 AndroidManifest.xml并进行动态切换


android { ... sourceSets { main{ // 应用 if(isModule.toBoolean()){ manifest.srcFile 'src/main/buildApp/AndroidManifest.xml' }else{// 插件 manifest.srcFile 'src/main/buildModule/AndroidManifest.xml' } } }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

(组件)src/main/buildApp/AndroidManifest.xml的内容可能如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.wong.modulea" > <application> <activity android:name=".WarehouseActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application>

</manifest>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

(插件)src/main/buildModule/AndroidManifest.xml的内容可能如下:
buildModule 的 AndroidManifest.xml, activity 等在这里可以正常注册。这里注册后主程序就可以不用写了。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.wong.modulea"> <application> <activity android:name=".WarehouseActivity"></activity> </application>

</manifest>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

(4)在app模块的build.gradle配置如下:

dependencies { ... if(!isModule.toBoolean()){ implementation project(path: ':modulea') }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这样就完成了。

Android 模块化开发过程中可能遇到的问题

1.资源名冲突
默认情况, library 的所有的 resource 为 public , 在模块化开发过程中很容易遇到资源冲突问题。两种解决方法:
(1)保护某些 resources 不被外部访问,通过创建res/values/public.xml来完成,至少添加一行,就会被视为 private。

<resources> <public name="mylib_app_name" type="string"/>
</resources>


  
 
  • 1
  • 2
  • 3
  • 4

(2)在 library 的 build.gradle 中添加 resourcePrefix , 则所有的资源须以此 prefix 开头,否则报错。注意,图片资源虽然不提示报错误,但是也需要修改名字。

android { ... buildTypes { ... } resourcePrefix 'my_prefix_'
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.依赖重复
解决方法:将所有的依赖都写在library层的module里,将所有的依赖统一一个入口给顶层的app用。

最后送上demo

谢谢阅读

文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_40763897/article/details/103801287

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。