android模块化时manifest问题,GitHub - ruanchaohouzi/MoreModuleSample: Android模块化开发实践——主要搭建Android组件化开发架构,便于...

一、组件化开发的优点:

1.减少整个项目的build时间,可以各个模块单独build。

2.保持各个模块的独立性,各个模块单独开发不受影响。

3.代码维护更加简单,可以迅速找到需要修改的模块代码。

二、组件化开发原理:

1.各个模块独立成一个ModuleLibrary,宿主Module , 公用库CommonLibrary,核心是通过参数isModuleRun在各个模块的Gradle里面控制,

控制各个模块四单独运行还是作为Library运行。

if (rootProject.ext.isModuleRun){

apply plugin: 'com.android.application'

}else{

apply plugin: 'com.android.library'

}

三、组件化的基本框架

1.每个组件可以单独运行,相互不受影响,核心是通过配置文件isModuleRun控制切换

2.通过路由控制调用各个模块,可以采取阿里的ARouter

四、具体实现原理

1.具体实现可以分为以下几步:

(1)解决模块独立运行还是作为Library运行问题(主要是Gralde配置),同时解决manifest合并问题。

(2)解决各模块Application合并问题,主要通过反射合并(核心点)

(3)解决各个模块之间的相互通信,主要采取阿里的开源框架ARouter

2.解决模块独立运行还是作为Library运行问题

(1)各个模块的第三方引用库、以及相关变量最好统一配置在根gralde中,方便各个模块引用相同的参数

根部gradle配置可变参数:

ext{

isModuleRun = false;//false:作为Lib组件存在, true:作为application存在

//butterknife

butterknife = "com.jakewharton:butterknife:8.4.0"

butterknifeCompiler = "com.jakewharton:butterknife-compiler:8.4.0"

butterknifePlugin = 'com.jakewharton:butterknife-gradle-plugin:8.4.0'

multidex = 'com.android.support:multidex:1.0.1'

}

(2)各个子模块gradle配置,通过参数isModuleRun来控制各个模块是否独立运行还是作为Library运行

空壳App配置:主要是通过参数isModuleRun确定需要引用的模块

dependencies {

compile project(':common')

if(!rootProject.ext.isModuleRun){

compile project(':robot')

compile project(':hotnews')

}

}

各个子模块的gradle配置:

主要是为了确定是模块独立运行,还是作为Library运行

if (rootProject.ext.isModuleRun){

apply plugin: 'com.android.application'

}else{

apply plugin: 'com.android.library'

}

主要是确定如果是独立模块,确定当前独立模块的包名

defaultConfig {

if(rootProject.ext.isModuleRun){

applicationId "com.ruanchao.hotnews"

}

}

分别确定模块独立运行的Manifest和作为库运行的Manifest,需要在模块对应路径下新建作为Library运行的Manifest

sourceSets {

main {

if (rootProject.ext.isModuleRun){

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

}else {

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

}

}

}

3、解决各模块Application合并问题

主要在Common模块创建公共类操作Application,主要新建以下几个类处理

BaseApplication:各个模块公用的Application

ApplicationDelegate:读取所有模块的Application信息

IApplicationLife:Application生命周期

IModuleConfig:各个模块反射得到的Application,通过该接口调用反射中类中的方法

ManifestParser:解析ManifestParser中的meta参数,以下重点介绍

(1)各个模块作为Library的manifest中配置meta参数,主要作为标志各个模块的Application入口,方便主模块反射获取子模块Application信息。其中name是当前模块Application的类名(注意不是真正的Application,只是实现了Application生命周期的类,因为Library中的Application是并独立运行的)

(2)解析meta参数,反射获取各个模块的Application信息,主要在ManifestParser中执行。返回信息是反射类后需要执行方法的接口IModuleConfig。

public class ManifestParser {

private Context mContext;

private static final String MODULE_VALUE = "IModuleConfig";

public ManifestParser(Context context){

mContext = context;

}

public List parseModuleConfig(){

List moduleConfigList = new ArrayList<>();

try {

ApplicationInfo applicationInfo = mContext.getPackageManager().getApplicationInfo(

mContext.getPackageName(), PackageManager.GET_META_DATA);

if(applicationInfo.metaData != null){

for (String key : applicationInfo.metaData.keySet()){

if (MODULE_VALUE.equals(applicationInfo.metaData.get(key))){

IModuleConfig iModuleConfig = parseClass(key);

moduleConfigList.add(iModuleConfig);

}

}

}

} catch (PackageManager.NameNotFoundException e) {

e.printStackTrace();

}

return moduleConfigList;

}

private IModuleConfig parseClass(String className){

try {

Class> forName = Class.forName(className);

return (IModuleConfig) forName.newInstance();

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

}

IModuleConfig的实现如下,主要把当前解析的Application信息插入到集合中,方便主Application调用。

public interface IModuleConfig {

void addApplicationLife(Context context, List applicationLifeList);

void addActivityLife(Context context, List activityLifecycleCallbacks);

}

(3)ApplicationDelegate,主要遍历执行各个子模块的Application信息,该类继承Application的生命周期IApplicationLife

public class ApplicationDelegate implements IApplicationLife {

List moduleConfigList = new ArrayList<>();

List applicationLifeList = new ArrayList<>();

List activityLifecycleCallbackList = new ArrayList<>();

@Override

public void attachBaseContext(Context baseContext) {

ManifestParser manifestParser = new ManifestParser(baseContext);

moduleConfigList = manifestParser.parseModuleConfig();

for (IModuleConfig moduleConfig : moduleConfigList) {

moduleConfig.addApplicationLife(baseContext, applicationLifeList);

moduleConfig.addActivityLife(baseContext, activityLifecycleCallbackList);

}

for (IApplicationLife applicationLife : applicationLifeList) {

applicationLife.attachBaseContext(baseContext);

}

}

@Override

public void onCreate(Application baseContext) {

for (IApplicationLife applicationLife : applicationLifeList) {

applicationLife.onCreate(baseContext);

}

for (Application.ActivityLifecycleCallbacks activityLifecycleCallbacks : activityLifecycleCallbackList) {

baseContext.registerActivityLifecycleCallbacks(activityLifecycleCallbacks);

}

}

@Override

public void onTerminate(Application baseContext) {

for (IApplicationLife applicationLife : applicationLifeList) {

applicationLife.onTerminate(baseContext);

}

for (Application.ActivityLifecycleCallbacks activityLifecycleCallbacks : activityLifecycleCallbackList) {

baseContext.unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks);

}

}

IApplicationLife的实现如下

public interface IApplicationLife {

void attachBaseContext(Context baseContext);

void onCreate(Application baseContext);

void onTerminate(Application baseContext);

}

(4)最后需要在主Application中执行各个子模块的Application中的方法。也就是在BaseApplication中执行

public class BaseApplication extends MultiDexApplication {

ApplicationDelegate applicationDelegate;

@Override

protected void attachBaseContext(Context base) {

super.attachBaseContext(base);

applicationDelegate = new ApplicationDelegate();

applicationDelegate.attachBaseContext(base);

}

@Override

public void onCreate() {

super.onCreate();

ARouter.init(this);

applicationDelegate.onCreate(this);

}

@Override

public void onTerminate() {

super.onTerminate();

applicationDelegate.onTerminate(this);

}

}

4.解决各个模块之间的相互通信,主要采取阿里的开源框架ARouter,可以详细看下阿里开源框架ARouter的API

(1)添加依赖和配置

android {

defaultConfig {

...

javaCompileOptions {

annotationProcessorOptions {

arguments = [ moduleName : project.getName() ]

}

}

}

}

dependencies {

// 替换成最新版本, 需要注意的是api

// 要与compiler匹配使用,均使用最新版可以保证兼容

compile 'com.alibaba:arouter-api:x.x.x'

annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'

...

}

(2)添加注解

@Route(path = "/RobotMainActivity/1")

public class RobotMainActivity extends AppCompatActivity

(3)初始化SDK

ARouter.init(this);

(4)发起路由操作

ARouter.getInstance().build("/HotNewsMainActivity/1").navigation();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值