在采用组件化之前,我负责的一个电商项目经历了1.0单模块版本、2.0多模块版本,3.0决定采用组件化来重构项目,并将项目开源,可供同样在做电商的android开发者参考、在研究android架构的同行者共同学习进步。在做之前,我们考虑三个问题,what、why和how,什么是组件化?为什么要进行组件化?如何进行组件化?
该电商项目源码请点击
组件化是指解耦复杂系统时将多个功能模块拆分、重组的过程。在Android工程表现上就是把app按照其业务的不同,划分为不同的Module,每个Module可独立作为一个app运行,也可作为整个app的子模块。
if (isModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
根据电商项目的业务特点,我们设计了如下架构图
从下往上来看,依次是通用组件、业务组件、业务模块、APP壳四大层。
同级组件间,因为没有相互依赖关系,所以不能相互调用,那么我们就遇到了通信的问题,如何来解决组件间通信,目前开源的有多种方案可以选择,用的最普遍的是阿里的ARouter,这里我们选择ARouter来解决我们的通信问题。
为了使我们的设计具有更强的灵活性和易用性,我们新增 lib_router 模块来对 arouter 做一层包装。
使用举例:在router模块中定义UserIntent.startLoginActivity,在各个组件中可直接调用
public class UserIntent {
public static void startLoginActivity() {
ModuleRouter.newInstance(USER_PROFILE_LOGIN_ACTIVITY).navigation();
}
}
//任意组件中使用
UserIntent.startLoginActivity();
各个方案比较请点击
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
}
}
public class ModuleConfig {
public static final String[] MODULE_LIST=
{
"com.jackting.module_goods.GoodsApplication",
"com.jackting.module_user.UserApplication",
};
}
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();
}
}
}
}
resourcePrefix "user_"
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/**'
}
}
}
}
常用的开发模式有MVC、MVP和MVVM三种,mvc中acitvity太重,model层和view层耦合性太强,mvvm做了双向绑定,但是xml不能复用、调试问题极其不方便,个人对MVP是情有独钟,虽然类会多一点,但是代码结构清晰,便于管理和维护。
dagger2的使用有两种,一种和android平台有关,使用更方便,但是对项目的侵入性很强,不能和组件化结合使用,另一种和android平台无关,但是可以和组件化结合使用,于是我们选择了后者。
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;
}
}
void inject(XxxActivity activity);
DaggerUserComponent.builder()
.appComponent(getAppComponent())
.build()
.inject(this);
dependencies {
classpath 'com.jakewharton:butterknife-gradle-plugin:10.1.0'
}
apply plugin: 'com.jakewharton.butterknife'
@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) {
}
}