设为首页 加入收藏

TOP

Android彻底组件化demo发布(二)
2017-10-13 10:37:07 】 浏览:4381
Tags:Android 彻底 组件 demo 发布
nStop() { router.removeService(ReadBookService.class.getSimpleName()); } }

在app中如何使用如reader组件提供的ReaderFragment呢?注意此处app是看不到组件的任何实现类的,它只能看到componentservice中定义的ReadBookService,所以只能面向ReadBookService来编程。具体的实例代码如下:

Router router = Router.getInstance();
if (router.getService(ReadBookService.class.getSimpleName()) != null) {
    ReadBookService service = (ReadBookService) router.getService(ReadBookService.class.getSimpleName());
    fragment = service.getReadBookFragment();
    ft = getSupportFragmentManager().beginTransaction();
    ft.add(R.id.tab_content, fragment).commitAllowingStateLoss();
}

这里需要注意的是由于组件是可以动态加载和卸载的,因此在使用ReadBookService的需要进行判空处理。我们看到数据的传输是通过一个中央路由Router来实现的,这个Router的实现其实很简单,其本质就是一个HashMap,具体代码大家参见源码。

通过上面几个步骤就可以轻松实现组件之间的交互,由于是面向接口,所以组件之间是完全解耦的。至于如何让组件之间在编译阶段不不可见,是通过上文所说的com.dd.comgradle实现的,这个在第一篇文章中已经讲到,后面会贴出具体的代码。

3 UI跳转

页面(activity)的跳转也是通过一个中央路由UIRouter来实现,不同的是这里增加了一个优先级的概念。具体的实现就不在这里赘述了,代码还是很清晰的。

页面的跳转通过短链的方式,例如我们要跳转到share页面,只需要调用

UIRouter.getInstance().openUri(getActivity(), "componentdemo://share", null);

具体是哪个组件响应componentdemo://share这个短链呢?这就要看是哪个组件处理了这个schme和host,在demo中share组件在自己实现的ShareUIRouter中声明了自己处理这个短链,具体代码如下:

private static final String SCHME = "componentdemo";
private static final String SHAREHOST = "share";
public boolean openUri(Context context, Uri uri, Bundle bundle) {
    if (uri == null || context == null) {
        return true;
    }
    String host = uri.getHost();
    if (SHAREHOST.equals(host)) {
        Intent intent = new Intent(context, ShareActivity.class);
        intent.putExtras(bundle == null ? new Bundle() : bundle);
        context.startActivity(intent);
        return true;
    }
    return false;
}

在这里如果已经组件已经响应了这个短链,就返回true,这样更低优先级的组件就不会接收到这个短链。

目前根据schme和host跳转的逻辑是开发人员自己编写的,这块后面要修改成根据注解生成。这部分已经有一些优秀的开源项目可以参考,如ARouter等。

4 集成调试

集成调试可以认为由app或者其他组件充当host的角色,引入其他相关的组件一起参与编译,从而测试整个交互流程。在demo中app和reader都可以充当host的角色。在这里我们以app为例。

首先我们需要在根项目的gradle.properties中增加一个变量mainmodulename,其值就是工程中的主项目,这里是app。设置为mainmodulename的module,其isRunAlone永远是true。

然后在app项目的gradle.properties文件中增加两个变量:

debugComponent=readercomponent,com.mrzhang.share:sharecomponent
compileComponent=readercomponent,sharecomponent

其中debugComponent是运行debug的时候引入的组件,compileComponent是release模式下引入的组件。我们可以看到debugComponent引入的两个组件写法是不同的,这是因为组件引入支持两种语法,module或者modulePackage:module,前者直接引用module工程,后者使用componentrelease中已经发布的aar。

注意在集成调试中,要引入的reader和share组件是不需要把自己的isRunAlone修改为false的。我们知道一个application工程是不能直接引用(compile)另一个application工程的,所以如果app和组件都是isRunAlone=true的话在正常情况下是编译不过的。秘密就在于com.dd.comgradle会自动识别当前要调试的具体是哪个组件,然后把其他组件默默的修改为library工程,这个修改只在当次编译生效。

如何判断当前要运行的是app还是哪个组件呢?这个是通过task来判断的,判断的规则如下:

  • assembleRelease → app
  • app:assembleRelease或者 :app:assembleRelease → app
  • sharecomponent:assembleRelease 或者:sharecomponent:assembleRelease→ sharecomponent

上面的内容要实现的目的就是每个组件可以直接在Androidstudio中run,也可以使用命令进行打包,这期间不需要修改任何配置,却可以自动引入依赖的组件。这在开发中可以极大加快工作效率。

5 代码边界

至于依赖的组件是如何集成到host中的,其本质还是直接使用compile project(...)或者compile modulePackage:module@aar。那么为啥不直接在build.gradle中直接引入呢,而要经过com.dd.comgradle这个插件来进行诸多复杂的操作?原因在第一篇文章中也讲到了,那就是组件之间的完全隔离,也可以称之为代码边界。如果我们直接compile组件,那么组件的所有实现类就完全暴露出来了,使用方就可以直接引入实现类来编程,从而绕过了面向

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇绑定服务 下一篇调用Android自带浏览器打开网页

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目