android电商组件化分配,android电商组件化设计(含源码):MVP+dagger+组件化

起源

在采用组件化之前,我负责的一个电商项目经历了1.0单模块版本、2.0多模块版本,3.0决定采用组件化来重构项目,并将项目开源,可供同样在做电商的android开发者参考、在研究android架构的同行者共同学习进步。在做之前,我们考虑三个问题,what、why和how,什么是组件化?为什么要进行组件化?如何进行组件化?

该电商项目源码请点击

什么是组件化

组件化是指解耦复杂系统时将多个功能模块拆分、重组的过程。在Android工程表现上就是把app按照其业务的不同,划分为不同的Module,每个Module可独立作为一个app运行,也可作为整个app的子模块。

为什么要进行组件化

为了解耦:把复杂系统拆分成多个组件,分离组件边界和责任,便于独立升级和维护

各个组件专注自身功能的实现,模块中代码高度聚合,只负责一项任务,也就是常说的单一职责原则;

各业务研发可以互不干扰、提高协作效率;

业务组件可进行拔插,灵活多变;

业务组件之间将不再直接引用和依赖,各个业务模块组件更加独立,降低耦合;

加快编译速度,提高开发效率

android如何进行组件化

在gradle.properties文件中增加常量:isModule=false

在各个组件模块的gradle中增加是否是组件的动态配置

if (isModule.toBoolean()) {

apply plugin: 'com.android.application'

} else {

apply plugin: 'com.android.library'

}

如果需要独立模块运行,则将gradle.properties中的isModule置为true,否则置为false,修改后rebuild一下;当然这样只是简单实现了组件的自动拆分和重组,更详细的实现请继续往下看

电商项目组件化之路

根据电商项目的业务特点,我们设计了如下架构图

219f89c9c081a0d62d01fb56038253cf.png

从下往上来看,依次是通用组件、业务组件、业务模块、APP壳四大层。

通用组件,又称业务无关组件,根据来源分为开源库和基础组件库,开源库是我们在项目中经常会用到的第三方库,比如okhttp、rxJava等,基础组件库是我们自己定义的和业务无关的组件,主要包括BaseMvp、工具类、自定义的Widget、http等

common_http: http通信组件

业务组件,和业务相关的组件

lib_push: 推送组件,负责推送服务

lib_share: 第三方分享

lib_im: 即时聊天的服务

lib_webview: 独立进程webview,用于和h5之间进行交互

业务模块,根据业务的联系紧密程度来拆分

module_main: 首页模块,包括启动页、欢迎页、首页等;

module_goods: 商品模块,包括商品分类、商品详情、商品搜索等;

module_user: 用户模块,包括个人中心、登录等;

module_order:订单模块,包括订单确认、订单列表等;

module_msg: 消息模块,包括客服消息等;

APP壳,是app的入口模块,包括manifest配置、加载各个模块、打包配置等,基于应用安全考虑,通过调用C层的加密方法将业务模块加密

组件化间通信

同级组件间,因为没有相互依赖关系,所以不能相互调用,那么我们就遇到了通信的问题,如何来解决组件间通信,目前开源的有多种方案可以选择,用的最普遍的是阿里的ARouter,这里我们选择ARouter来解决我们的通信问题。

为了使我们的设计具有更强的灵活性和易用性,我们新增 lib_router 模块来对 arouter 做一层包装。

使用举例:在router模块中定义UserIntent.startLoginActivity,在各个组件中可直接调用

public class UserIntent {

public static void startLoginActivity() {

ModuleRouter.newInstance(USER_PROFILE_LOGIN_ACTIVITY).navigation();

}

}

//任意组件中使用

UserIntent.startLoginActivity();

第三方可选择方案

各个方案比较请点击

阿里的ARouter

CC

ActivityRouter

组件初始化

在common层定义接口 IApplication

public interface IApplication {

void onCreate(Application application);

}

在各个组件中实现该接口

public class UserApplication implements IApplication {

public static Application sApp = null;

@Override

public void onCreate(Application application) {

sApp = application;

// to do init

}

}

在common中新增类ModuleConfig,用来存储各个组件的application路径

public class ModuleConfig {

public static final String[] MODULE_LIST=

{

"com.jackting.module_goods.GoodsApplication",

"com.jackting.module_user.UserApplication",

};

}

在CommonApplication中加载各个组件的application

public class CommonApplication extends Application {

public void onCreate() {

modulesApplicationInit();

}

private void modulesApplicationInit(){

for (String moduleImpl : ModuleConfig.MODULE_LIST){

try {

Class> clazz = Class.forName(moduleImpl);

Object obj = clazz.newInstance();

if (obj instanceof IApplication){

((IApplication) obj).onCreate(this);

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

}

}

}

}

组件的gradle配置

资源命名前缀定义:为了防止不同组件间资源命名重复问题,我们对各个组件定义不同的命名前缀,这样不同组件间的资源命名便一定不会重复

resourcePrefix "user_"

整个项目一起运行和组件单独运行时,AndroidManifest文件中四大组件的配置一定是不同的(比如启动activity的配置),所以两种模式要使用不同的manifest文件

sourceSets{

main{

if(isModule.toBoolean()){

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

} else {

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

java{

//全部module一起编译的时候剔除debug目录

exclude '**/**/debug/**'

}

}

}

}

MVP+dagger的引入

常用的开发模式有MVC、MVP和MVVM三种,mvc中acitvity太重,model层和view层耦合性太强,mvvm做了双向绑定,但是xml不能复用、调试问题极其不方便,个人对MVP是情有独钟,虽然类会多一点,但是代码结构清晰,便于管理和维护。

dagger2的使用有两种,一种和android平台有关,使用更方便,但是对项目的侵入性很强,不能和组件化结合使用,另一种和android平台无关,但是可以和组件化结合使用,于是我们选择了后者。

dagger2的引入

在CommonApplication定义AppComponent

public class CommonApplication extends Application {

private static AppComponent appComponent;

private void initInjector(){

appComponent = DaggerAppComponent.builder()

.appModule(new AppModule(sApplication))

.build();

}

public static AppComponent getAppComponent() {

return appComponent;

}

}

在Component在增加注入配置

void inject(XxxActivity activity);

在activity中初始化注入

DaggerUserComponent.builder()

.appComponent(getAppComponent())

.build()

.inject(this);

butterknife在组件化中的使用

在项目根目录下的build.gradle中增加classpath

dependencies {

classpath 'com.jakewharton:butterknife-gradle-plugin:10.1.0'

}

在各个组件/模块中增加插件配置

apply plugin: 'com.jakewharton.butterknife'

activity/fragment中使用,使用R2,而非R

@BindView(R2.id.et_user_login_username)

EditText etName;

@OnClick({R2.id.btn_login})

public void doClick(View view){

int id = view.getId();

if (id == R.id.btn_login) {

}

}

参考

知乎 Android 客户端组件化实践

浅谈项目架构重构之路——组件化与MVP

架构师的思维,聊一聊APP组件化的那些事儿 备用

WanAndroid架构源码

仿京东app

MVPArms

联系我们

邮箱:itdjx@qq.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值