@zhuhf
2018-01-16T15:00:19.000000Z
字数 2561
阅读 965
旨在规范各个子模块(子工程)对外暴露 数据、UI 的方式,提供统一的接口和编码实现。
暴露数据的方式是合理的,因为对外只在 common 模块暴露了接口的定义。
而暴露 Activity,需要将对应的 path 下沉到 common 模块,各个子模块使用 ARouter 结合对应的 path,跳转到对应的界面,并传递数据。
为了提高编码效率,通常会统一将所有需要暴露的 Activity 的跳转方法写到 ActivityLauncher 中,采取集中管理的方式,这种方式存在以下几个问题:
这种方式导致了 ActivityLauncher 的急剧膨胀,截止目前已经有超过 2400+ 行代码,随着业务的增长,这个类的增长将是不可控的。
另外,模块内部的 UI 跳转,到底是使用 Android 自带的 Intent 方式,还是使用 ARouter 来处理?没有一个明确的说词,经常取决于编码代码的人的习惯。
原则:高内聚、低耦合,针对接口编程而不是实现。
子模块只对外暴露对应的接口,如何实现属于内部细节,外部不需要了解。
Activity 提供静态跳转方法入口,内部用 Intent 还是 ARouter 不做限制,但如果使用 ARouter,对应的 path 请放在自己的模块,因为外部不需要知道
@Route(path = AtnOrderDetailActivity.PATH)
public class AtnOrderDetailActivity extends BasicActivity {
/**
* path 定义
*/
static final String PATH = "/Auction/AtnOrderDetailActivity";
public static void start(Context activity, String orderNo) {
ARouter.getInstance().build(PATH)
.withString("orderNo", orderNo)
.navigation(activity);
}
public static void start(Context activity, String orderNo) {
Intent intent = new Intent(activity, AtnOrderDetailActivity.class);
intent.putExtra("orderNo", orderNo);
activity.startActivity(intent);
}
}
以上两种实现都是 OK 的。
模块对外暴露的 数据、UI,定义在 common 模块的服务接口
public interface ModuleAuctionService extends SchemeProvider {
/**
* 订单详情
* @param orderNo 订单号
*/
@UiThread
void gotoOrderDetail(Context activity, String orderNo);
}
服务的具体实现放在各自模块
@Route(path = IntentPath.SERVICE_AUCTION)
public class ModuleAuctionServiceImpl implements ModuleAuctionService {
// ...
@Override
public void gotoOrderDetail(Context activity, String orderNo) {
AtnOrderDetailActivity.gotoAuctionOrderDetail(orderNo);
}
}
这里需要提一下,gotoOrderDetail
内部仍然要使用对应的 Activity 的静态方法去跳转。
Scheme 处理器
同样,也是属于内部模块,也要使用 Activity 的静态方法去跳转。
public class AtnSchemeProcessor implements IProcessor {
static final String JCY_AUCTION_DETAIL = "JCY_Auction_Detail";
public String[] getAction() {
return new String[]{JCY_AUCTION_DETAIL};
}
@Override
public boolean handleScheme(FragmentActivity activity, @NonNull String schemeUrl, @NonNull String action, Map<String, String> params) {
switch (action) {
case JCY_AUCTION_DETAIL:
if (!Utils.checkLogin(activity, schemeUrl)) {
return true;
} else {
String auctionId = params.get("auctionId");
AuctionDetailActivity.actionStart(activity, auctionId);
}
break;
}
return true;
}
}
服务使用方式
ModuleAuctionService service = ServiceLauncher.getServiceByName(IntentPath.SERVICE_AUCTION);
if (service != null) {
service.gotoOrderDetail(this, orderNo);
}
目前 ServiceLauncher 的做法是:包装了一层方法,供外部调用。
个人觉得有点冗余了,为了避免 ServiceLauncher 走上 ActivityLauncher 的老路,建议大家不要去这么做了。
遵循以上几个原则之后,原有 ActivityLauncher 的所有方法,被分别移到了各个子模块中去。
如果需要查询某个子模块对对外暴露的方法,只需要去 common 模块查看对应的接口定义就好了
模块对外接口定义,详见 module_commonlib 模块 service 包。