Android架构大牛聚集之地

全面组件化---DDComponentForAndroid分析(

2017-11-09  本文已影响2619人  五谷观精分道长

前言

关于组件化,其实从毕业到现在都在使用组件化的开发方式。因为公司有多个android开发人员,平时需要协同开发。但是之前的组件化方案都是公司的老员工留下来的东西,虽然也能达到组件化开发的目标。但使用起来不是很方便,简单来说就是---僵硬。

后来前辈离职,具体前辈突然离职了,作为应届生的我。正好这是一个机会,于是我准备开始实现自己的方案。

半个月前看到了简书上的文章:
Android彻底组件化demo发布
Android彻底组件化方案实践
颇受启发,虽然作者写的很详细。但是水平问题,一时看懂有点难。所以上下分析了将近三天,才有一点眉目。由于作者是从一个开发者视角讲解的框架,所以作为使用者理解有点模糊。

我打算从使用者的角度来分析这个框架,从一个新的项目如何一步一步的引入这个组件化方案。水平有限,如有误差,还望谅解。

1.全面组件化---DDComponentForAndroid分析(1)
2.全面组件化---DDComponentForAndroid分析(2)
3.全面组件化---DDComponentForAndroid分析(3)

一点姿势补充(摘抄)

组件化和模块化以及插件化

模块化是一种指导理念,其核心思想就是分而治之、降低耦合。而在Android工程中如何实施,目前有两种途径,也是两大流派,一个是组件化,一个是插件化。

组件化需要解决的几大问题

整个框架结构

6650461-92c8e8a0a078f6ef.png

如何使用到自己的全新项目中

首先下载源码

https://github.com/luojilab/DDComponentForAndroid

主要是用来做参考和对比的,也可以不下载

新建自己的项目

  1. 新建一个名为"zujianhua"的工程,并导入一些基本依赖库。

为了方便起见,我使用了参考源码中的代码,后期会改为自己的代码。

主要是三个library:
:componentservice, :basicres, :basiclib

依赖关系:app-->componentservice-->basicres-->basiclib

作用:

  • componentservice: 组件服务,用于数据传输
  • basicres: 公共资源
  • basiclib: 公共代码
  1. 导入插件 build-gradle 非必需

为什么说非必需,因为可以在其他地方导入。发布到一个maven 仓库中,提供引用即可。

为了方便分析,这里先导入到项目里,只发布到本地文件系统。(后面讲解如何发布到meven)

关于搭建maven 仓库

搭建本地的nexus-maven-仓库

build-gradle 是一个gradle 插件工程,需要生成对应的jar文件提供给.gradle 文件使用:

点击右上角-->Gradle-->buid-gradle-->Tasks-->upload-->uploadArchives

点击即可,等待:

gradle插件发布到本地仓库.png

出现新的文件夹:repo,也就是插件发布的地址。

gradle生成的文件夹.png
  1. 关键步骤,使用插件
repositories {
        google()
        jcenter()
        maven {
            url uri('./repo')
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
        classpath 'com.mrzhang.andcomponent:build-gradle:0.0.2'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

mainmodulename=app

意义:告知插件 工程主项目

具体调用代码: 在gradle插件工程里面

  1. 新增 gradle.properties 文件 配置该 组件的信息

暂时先配置:

isRunAlone=true

isRunAlone 标记当前是否需要单独调试,为ture就表示需要单独调试。不会拉起其他组件。

2.去掉 apply plugin: 'com.android.application'
改为 apply plugin: 'com.dd.comgradle'表示应用自己的插件。
而这个插件会判断当前你应该是
apply plugin: 'com.android.application'还是
apply plugin: 'com.android.library'

运行app 测试一下:
报错

Error:Execution failed for task ':app:transformClassesWithComponentCodeForDebug'.
> you should set applicationName in combuild

原因没有配置combuild,因为在插件中需要combuild 判断组件加载方式。

在什么时机加载组件以及如何加载组件?目前com.dd.comgradle提供了两种方式,字节码插入和反射调用。

所以我们在build.gradle增加:

combuild {
    applicationName = 'com.example.administrator.zujianhua.AppApplication'
    isRegisterCompoAuto = true
}

接下来开始第二部分:拆分业务,如何让单独的组件跑起来

新建一个module

1.取名OneCompone 表示是第一个

依赖关系OneCompone-->componentservice-->basicres-->basiclib

  1. 修改组件gradle.properties

组件的工程目录下新建文件gradle.properties文件,增加以下配置:

isRunAlone=true
  1. 应用组件化编译脚本
    同上,引入apply plugin: 'com.dd.comgradle',并配置combuild
  1. 为了解决模块的单独运行,插件需要配置runalone 资源文件。
    专门配置组件单独运行的资源。
    具体如下:在组件内 于java同级新建runalone 目录
    (如想修改,可查看插件源码)
    为方便起见,我直接复制源代码中的文件夹。


    QQ截图20171109153326.png

    sync一下,再看一下目录结构:


    QQ截图20171109155310.png

我们可以尝试单独安装 两个组件到手机上:

QQ截图20171109155702.png

这样我们就做到了单独调试。


接下来如何数据传递:

  1. 引入路由框架componentlib
    componentservice>componentlib

整个框架结构变成:

路由:这个应该可以修改成自己的路由框架

  1. 注意这里在debug 时候需要引入onecomponent

所以修改app的gradle.properties文件

isRunAlone=true
debugComponent=onecomponent

debugComponent 就表示 引入onecomponent 组件 在debug下

  1. 配置路由添加Service

service在这里作为一个数据提供的角色,可以在任何地方通过路由获取到service。

public interface OneService {

    Fragment getOneFragment();
}
public class OneServiceImpl implements OneService {
    @Override
    public Fragment getOneFragment() {
        return new OneFragment();
    }
}
public class OneAppLike implements IApplicationLike {

    Router router = Router.getInstance();

    @Override
    public void onCreate() {
        //注入
        router.addService(OneService.class.getSimpleName(), new OneServiceImpl());
    }

    @Override
    public void onStop() {
        //移除
        router.removeService(OneService.class.getSimpleName());
    }
}

由于组件分离,无法直接调用。所以提供两种调用方式:

  1. isRegisterCompoAuto 设置为true,由com.dd.comgradle插件完成引用。
    (如何做到的,可以看接下来的插件分析)
  2. isRegisterCompoAuto 设置为false,则需要手动加载。
    假设 app需要加载 one ,需要:
public class AppApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        //如果isRegisterCompoAuto为false,则需要通过反射加载组件
        Router.registerComponent("com.example.onecomponent.applike.OneAppLike");

    }
}

同理,如果a需要加载b。需要在a的application里面注册b。

 Router router = Router.getInstance();
        if (router.getService(OneService.class.getSimpleName()) != null) {
            OneService service = (OneService) router.getService(OneService.class.getSimpleName());
Fragment            fragment = service.getOneFragment();

尝试启动:

device-2017-11-09-171359.png

UI跳转

这部分其实没什么讲的,而且各个路由框架有自己的跳转方式以及配置方法。

这里看一下源码中的路由框架如何跳转的

  1. 新建twocomponet,配置同上

  2. 添加twoactivity,配置runalone

  3. TwoUIRouter继承IComponentRouter接口,实现路由跳转内容

  4. TwoApplike 同样把TwoUIRouter加入到Router中

  5. 设置isRegisterCompoAuto 为true或者 手动注册。

Router.registerComponent("com.huruwo.twocomponent.applike.TwoAppLike");

6.代码跳转 从onefragement-->twoactivity

 UIRouter.getInstance().openUri(getActivity(), "component://two", null);

效果:

ui路由.gif

这篇文章已经够长了,先写到这里吧。

总结

这个部分解决了组件化的几个难点:

这里遗留了两个问题:

将在下篇文章中引入解决。

相关源代码已同步到github
https://github.com/HuRuWo/ZuJianHua

上一篇下一篇

猜你喜欢

热点阅读