组件化的由来:
随着APP版本不断的迭代,新功能的不断增加,业务也会变的越来越复杂,APP业务模块的数量有可能还会继续增加,而且每个模块的代码也变的越来越多,这样发展下去单一工程下的APP架构势必会影响开发效率,增加项目的维护成本,每个工程师都要熟悉如此之多的代码,将很难进行多人协作开发,而且Android项目在编译代码的时候电脑会非常卡,又因为单一工程下代码耦合严重,每修改一处代码后都要重新编译打包测试,导致非常耗时,最重要的是这样的代码想要做单元测试根本无从下手,所以必须要有更灵活的架构代替过去单一的工程架构。
几乎任何情况下都可以使用,最适合业务功能复杂的大型项目。
1实现代码解耦,复用,使代码更加清晰。
2有利于团队开发,使得开发人员之间职责明确,互不干扰。
3加快编译速度,提高开发效率、降低项目维护难度。
1在App和lib之间切换的时候对一些控件注入的框架支持不友好,如Butterknife
2作为Application时,不适合在application中定义方法。
例如我们有一个登入的模块和我的模块,这两个模块和主模块之间的(他们的交互,模块与模块之间)通过一个共有libs,这里是baselibrary。他们之家的关系如下图:
我们建立一个项目,有主app,一个baselib,两个单独模块login和mine模块
在项目的gradle.properties文件夹下配置全局的环境变量及对应的配置
例如:
#全局配置gradle环境
compile_Sdk_Version = 26
min_Sdk_Version = 15
target_Sdk_Version = 26
#配置组件是否可以独立运行
loginRunAlone=false
mineRuneAlone=false
在app的build.gradle
两个独立的模块配置:
解释下,由于两个独立的模块在lib和模块之间的切换,所以是插件还是模块等信息是动态配置,加载的minifest也是不同的,
如果不是独立的模块加载的minfest如下:
如果是的话,和之前的没什么区别。
我们在baseLIbs下定义了一些参数及类,登入模块通过实现ILoginService接口 ,Mine模块通过IMineService接口与其他模块交互,同时baselib下维护了一个单例如下
public class ServiceFactory {
private final static ServiceFactory instancce=new ServiceFactory();
private ServiceFactory(){}
public static ServiceFactory getInstancce(){
return instancce;
}
private ILoginService mILoginService;
private IMineService mIMineService;
public ILoginService getILoginService() {
if (mILoginService == null) {
mILoginService=new EmptyService();
}
return mILoginService;
}
public void setILoginService(ILoginService ILoginService) {
mILoginService = ILoginService;
}
public IMineService getIMineService() {
return mIMineService;
}
public void setIMineService(IMineService IMineService) {
mIMineService = IMineService;
}
}
在baseLIbs Appconfi类包装着两个模块的具体application类名,
public class AppConfig {
public static final String[] baseConfig={
"com.rk.logincomponent.LoginApplication",
"com.rk.minecomponent.MineApplication"
};
}
在login模块和mine模块和主app的application分别如下:
public class LoginApplication extends Application implements IBaseApp {
private static Application sApplication;
public static Application getApplication() {
return sApplication;
}
@Override
public void onCreate() {
super.onCreate();
initializal(this);
}
@Override
public void initializal(Application application) {
sApplication=application;
ServiceFactory.getInstancce().setILoginService(new LoginService());
}
}
public class MineApplication extends Application implements IBaseApp {
private static Application sApplication;
public static Application getApplication() {
return sApplication;
}
@Override
public void onCreate() {
super.onCreate();
initializal(this);
}
@Override
public void initializal(Application application) {
sApplication=application;
ServiceFactory.getInstancce().setIMineService(new MineServices());
}
}
public class MainApplication extends Application implements IBaseApp {
private static Application sApplication;
public static Application getApplication() {
return sApplication;
}
@Override
public void onCreate() {
super.onCreate();
initializal(this);
}
@Override
public void initializal(Application application) {
for (String s : AppConfig.baseConfig) {
try {
//通过配置文件的Application的路径,实例化,并传递给对应模块
Class> clazz = Class.forName(s);
Object o = clazz.newInstance();
if (o instanceof IBaseApp) {
((IBaseApp)o).initializal(this);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
三者都实现baselib的IbaseApp接口
public interface IBaseApp {
void initializal(Application application);
}
登入模块具体的实现类
public class LoginService implements ILoginService {
@Override
public void lanuch(Context context, String targetClass) {
Intent intent = new Intent(context, LoginActivity.class);
context.startActivity(intent);
}
@Override
public Fragment newUserInfoFragment(FragmentManager fragmentManager, int viewId, Bundle bundle) {
UserInfoFragment fragment = new UserInfoFragment();
fragment.setArguments(bundle);
fragmentManager.beginTransaction().add(viewId, fragment).commit();
return null;
}
}
Mine模块具体的实现类
public class MineServices implements IMineService {
@Override
public void lanuch(Context context, int userId) {
Intent intent=new Intent(context,MainActivity.class);
intent.putExtra("id",userId);
context.startActivity(intent);
}
}
主界面的调用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/*
* 跳转到登入组件
* */
public void toLogin(View view) {
ServiceFactory.getInstancce().
getILoginService().lanuch(MainActivity.this, "");
}
/*
* 跳转到我的组件
* */
public void toMine(View view) {
ServiceFactory.getInstancce().getIMineService()
.lanuch(MainActivity.this, 12);
}
/*
* 显示登入组件的fragemnt
* */
public void toShowFragemnt(View view) {
Bundle bundle = new Bundle();
ServiceFactory.getInstancce().getILoginService()
.newUserInfoFragment(getSupportFragmentManager(), R.id.container, bundle);
}
}
具体的demo在https://github.com/wyj3531/Demo