Android 模块化开发

目录

一、模块化浅谈

1. Android 模块化开发介绍;

模块化开发思路就是:单独开发每个模块,用集成的方式把他们组合起来,就能拼出一个app。app可以理解成很多功能模块的组合,而且有些功能模块是通用的,必备的,像自动更新,反馈,推送,都可以提炼成模块,和搭积木很像,由一个壳包含很多个模块。

2.Android 模块化开发的好处;

模块升级会单独升级,升级的时候往往不只是增加资源,有时候会去删资源,这样做和其它的模块的资源不掺乎,我用umeng的自动更新sdk时就需要我连着资源一块进来,加进来容易以后不想用umeng的了再挑出去就很费事了。再假如push开始用的百度的后来换成极光的,对app的组合者其实是不关心的,对他影响很小。解耦很好。如果是主力带实习生这种开发的话,核心代码就不用和他们分享,让他们去做独立的功能,做好直接调用就行。以后整理代码,重构什么的都只重构这个模块的代码,他们不会不小心改了核心代码。


二、模块化开发的架构分层

1407686-2a3990b4b781784e.png
1407686-0635652ee1b4040b.png

命名建议:
底层:Library
中间层:Module + 业务或功能名字
上层:App + 项目名字

建议分层进行

  • 底层:包含基础库和底层库
    • 基础库:
      包含所有模块需要的依赖库,以及一些工具类,比如封装了的常用网络请求,封装图片处理fresco,数据库相关等,还包含所有模块需要的依赖库;
    • 底层库:
      主要是使用C/C++开发的跨平台的引擎或者库,以so的形式存在。例如:游戏引擎cocos2d
  • 中间层
    首先、分模块肯定要按照功能分,独立的一个功能,不能杂。比如、更新、登录、分享、播放,都可以。
    其次、我采取aar的形式作为模块的最小单位,为什么是aar不是jar,更不是library,因为jar不能带资源只能带java代码,library的话太容易被修改了,aar的好处是能带资源并且是编译好的,不能被修改。保证了模块的版本不会在被别人调用的时候随意修改,如果想修改就要联系做aar的人,让他去升级aar的版本。
    用android studio,打aar用maven;aar其实就是依赖,只不过之前的依赖都是存到了maven远程库里,自己用的话可以自己建和私有的maven库,太蛮烦的话可以直接用本地的aar文件做依赖。
  • 上层
    将所有的业务模块聚合在一起,加上配置,形成主应用,一个模块化做的好的应用,主应用应该很简单,并且非常的稳定。

三、如何进行Android 模块化开发

进行Android 模块化开发前先复习一个基础知识,介绍一下 Studio 项目结构。


QQ截图20161114100811.png
  • MyApplication 整个项目目录
  • app 项目中app模块目录
  • settings.gradle 定义项目包含哪些模块
  • app/build/ app模块build编译输出的目录
  • app.iml app模块的配置文件
  • External Libraries 项目依赖的Lib,编译时自动下载的
    可以看出 Studio 新建的项目自身就是一个模块化项目,MyApplication 是整个项目,而app是一个模块,所以在后续自行增加更多的功能模块。
1.创建 Module 模块;

将所需的模块在对应项目的Project目录下拷贝出来,粘贴到要开发的项目的Project根目录下即可。也可以直接在project下新建一个Module

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

一个模块这样就创建完成了。默认的名字是app,根据项目的需要将模块的名字进行修改,直接Refactor > Rename...即可

1479092110399.png

2.将 Module 模块引入主项目中;

设置setting.gradle 中

include ':projectName'

设置后发现项目目录下增加了一个模块

QQ截图20161114111017.png

weather模块下的build.gradle进行sync操作后,

QQ截图20161114111211.png

蓝色小茶杯变成了小手机的图标

在主模块的build.gradle中设置

dependencies {
    ...
    compile project(':projectName')
    ...
}
3.模块中 application 和 library 状态切换配置;

<font color=red>组件化不是插件化,插件化是在[运行时],而组件化是在[编译时]。插件化是基于多APK,而组件化本质上还是只有一个APK。</font>

  1. 设置一个开关控制applicationlibrary状态切换
    我们在开发的时候,Module如果是一个库,会使用com.android.library插件,如果是一个应用,则使用com.android.application插件,接下来根据这个变量来进行判断并且实现状态切换。
    Project根目录下gradle.properties中设置变量来控制。

    asApp=false
    ...
    

    asApp=false:表示这个模块是一个Module;
    asApp=true:表示这个模块是一个app;

  2. 依赖项目中build.gradle配置
    在模块的build.gradle的开头处设置。

    // 开头处设置
    if (IsBuildModule.toBoolean()) {
        apply plugin: 'com.android.application'
    } else {
        apply plugin: 'com.android.library'
    }
    android {
        ...
        defaultConfig {
            // library 下删除 applicationId
            if (IsBuildMudle.toBoolean()) {
                applicationId "com.qsp.weather"
            }
            ....
        }
    }
    
  3. 提供两套 AndroidManifest.xml并进行动态切换
    mainfest文件也需要提供两套

    android {
        ...
        sourceSets {
            main {
                if (IsBuildModule.toBoolean()) {
                    manifest.srcFile 'src/main/buildModule/AndroidManifest.xml'
                } else {
                    manifest.srcFile 'src/main/buildApp/AndroidManifest.xml'
                }
            }
        }
    }
    
    
    • buildModule 的 AndroidManifest.xml, activity 等在这里可以正常注册。这里注册后主程序就可以不用写了写在哪里都可以。

      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.qsp.weather">
          <application
              android:allowBackup="true"
              android:supportsRtl="true">
          </application>
      </manifest>
      

四、Project 中模块以 aar 方式引入;

模块化方式分两种,第一种是以aar的方式引入项目中,因为有些模块在开发中可能功能不稳定或是不成熟,以arr形式引入不方便进行修改,所以这时候就可以以模块源码的方式引入。

1.导出 aar;

Android Library项目的gradle脚本在开头声明
apply plugin: 'com.android.library'
执行./gradlew assembleRelease然后在build/outputs/aar文件夹里生成aar文件

2.引用本地的aar;

生成aar之后下一步就是如何引用本地的aar文件?本地的aar文件并没有像引用jar文件这么简单,官方也没有提供解决方案。好在国外的一些前辈总结出了方法,下面就以test.aar文件为例来详述下方法。
1.把aar文件放在一个文件目录内,比如就放在libs目录内
2.在app的build.gradle文件添加如下内容

repositories {
    flatDir {
        dirs 'libs' //this way we can find the .aar file in libs folder
    }
}

3.之后在其他项目中添加一句gradle依赖便方便的引用了该library

dependencies {
    compile(name:'test', ext:'aar')
}

五、Android 模块化开发过程中遇到的问题

1.资源名冲突;

Android Studio 默认 library 的所有的 resource 为 public , 所以在模块化开发过程中总会遇到资源冲突问题。列出两种解决方法。

  • 方法一:
    保护某些 resources 不被外部访问,可以创建res/values/public.xml,因为 public 是关键词,搜易需要用 new file 的方式创建。至少添加一行,为添加的视为 private。

    <resources>
        <public name="mylib_app_name" type="string"/>
    </resources>
    
  • 方法二:
    在 library 的 build.gradle 中添加 resourcePrefix , 则所有的资源须以此 prefix 开头,否则报错。注意,图片资源虽然不提示报错误,但是也需要修改名字。

    android {
        ...
        buildTypes {
        ...
        }
        resourcePrefix 'my_prefix_'
    }
    
2.重复依赖;

将所有的依赖都写在library层的module,将所有的依赖同意成一个入口给上层的app去引用。

3.控制台报错解决;
Error:Module 'qsp_release:libLive:unspecified' depends on one or more Android Libraries but is a jar

报这个错误的场景,Moudle A 的build.gradle

apply plugin: 'java'
...
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':library')
    ...
}

可以看出 Moudle A 是一个jar形式的依赖模块,而libraryapply plugin: 'com.android.library'所以引用报如上错误。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容