APP模块化组件化
2018-04-10 本文已影响0人
JayGengi
APP模块化组件化
该库部分思想借鉴了"得到"APP:
个人demo地址:MyComponent
得到开源地址: 得到APP
组件化缘故:
当项目逐渐变大的时候,每次你改动了很小的一部分,你也需要重新编译整个APP,举个例子,修改了个人中心样式显示,就得重新编译整个APP.当随着业务的增多,代码变的越来越复杂,每个模块之间的代码耦合变得越来越严重,解耦问题急需解决,同时编译时间也会越来越长。
组件化效果:
毫无悬念,组件化势在必行,在网上看了很多相关的资料,对组件化有一个初步的了解,然后就开始组件化了,下面1以我自己的项目为例,放两张实际项目已经组件化之前跟之后的图对比一下。


可以明显的发现我们的Module变多了,组件化最大的好处就是可以模块可以单独开发调试,这样效率一下子就上来了,就拿XX模块举例,XX实际上就只有三个界面:首页|列表页|详情页.可以说想慢都慢不下来.
组件化要点:
- 组件与组件跳转(Router)
- 组件与组件之间依赖服务
- 广播(EventBus)
- 组件以lib和application形式存在(可独立运行)
组件化模块介绍:
- app(主项目,负责集成众多组件,控制组件的生命周期)
- basiclib(公共的基础库,一些第三方的库(网络图片\请求\公共类等))
- basicres(定义了全局通用的theme和color等公共资源)
- build-gradle(组件化编译的gradle插件,也是整个组件化方案的核心)
- componentlib(组件化的基础库(比如router初始化))
- componentservice(组件之间的服务库)
- hotelcomponent(模块组件[测试用例])
- sceniccomponent(模块组件[测试用例])
组件化项目实际应用:
在demo中初步实现的场景是:主项目app 集成Hotel和Scenic两个组件,两者提供fragment给app模块调用,在这里就简单的说下集成hotel的过程.
1.首先hotel组件在componentservice中定义自己的服务
/**
* 获取酒店列表
* create by gengy 60167
* at 18-3-21 下午5:36
*/
public interface GetHotelListService {
Fragment GetHotelListFragment();
}
2.然后在hotel的组件工程中,提供具体的实现类
/**
* 接口的实现(Impl拼错了,大写的尴尬,后面也会继续维护demo,添加更完善的内容)
* create by gengy 60167
* at 18-3-21 下午5:35
*/
public class HotelFragmentImlp implements GetHotelListService {
@Override
public Fragment GetHotelListFragment() {
return new HotelListFragment();
}
}
3.提供了具体的实现类之后,想要使用组件对外的服务需把实现类注册到Router中,这里定义了onCreate和onStop两个生命周期方法,对应组件的加载和卸载。
public class HotelAppLike implements IApplicationLike {
Router router = Router.getInstance();
@Override
public void onCreate() {
router.addService(GetHotelListService.class.getSimpleName(), new HotelFragmentImlp());
}
@Override
public void onStop() {
router.removeService(GetHotelListService.class.getSimpleName());
}
}
4.最后在主项目APP中面向Hotel提供的service找到提供的实现
private void setFragment() {
fragmentManager = getSupportFragmentManager();
homeFragment = new MainFragment();
Router router = Router.getInstance();
Router.registerComponent("com.jaygengi.hotel.applike.HotelAppLike");
Router.registerComponent("com.jaygengi.scenic.applike.ScenicAppLike");
GetHotelListService hotelListService = (GetHotelListService)router.getService(GetHotelListService.class.getSimpleName());
GetScenicListService ScenicListService = (GetScenicListService)router.getService(GetScenicListService.class.getSimpleName());
fragmentList = new ArrayList<Fragment>();
fragmentList.add(homeFragment);
fragmentList.add(hotelListService.GetHotelListFragment());//酒店列表
fragmentList.add(ScenicListService.GetScenicListFragment());//景区列表
setFrag();
}
组件之间的通信通过广播(EventBus)
demo中写的是:Scenic中填写内容,button按钮点击把内容替换到Hotel组件列表第一条酒店内容中.
EventBus操作起来很简单:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new HotelData(edit.getText().toString()));
}
});
Hotel注册EventBus并做处理
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.common_fragment_main, container, false);
ButterKnife.bind(this, view);
instance = this;
//注册EventBus
EventBus.getDefault().register(this);
setAdapter();
loadData();
return view;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void RfHotelData(HotelData hotel){
hotelList.get(0).setHotelNm(hotel.getHotelNm());
baseAdapter.setNewData(hotelList);
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
组件化总结:
利端:
- 每个模块都可以单独调试,节省编译时间
- 可以共享工具类,网络库等
- 快速测试
- 公司业务繁重,可以不断复用模块,节省开发时间
- 积累开发工具(个人)
弊端:
- 组件之间存在业务联系(componentService)
- 资源命令重复(组件中build.gradle resourcePrefix命名)
- 引用冲突(框架中添加了dependencies.gradle[作用:统一管理版本,第三方引用等])