美文网首页
android 组件化

android 组件化

作者: sk强仔 | 来源:发表于2017-10-24 17:26 被阅读0次

    一、模块化、组件化与插件化

    项目发展到一定程度,随着人员的增多,代码越来越臃肿,这时候就必须进行模块化的拆分。在我看来,模块化是一种指导理念,其核心思想就是分而治之、降低耦合。而在Android工程中如何实施,目前有两种途径,也是两大流派,一个是组件化,一个是插件化。

    提起组件化和插件化的区别,有一个很形象的图:

    组件化和插件化对比.png

    上面的图看上去比较清晰,其实容易导致一些误解,有下面几个小问题,图中可能说的不太清楚:

    ·组件化是一个整体吗?去了头和胳膊还能存在吗?左图中,似乎组件化是一个有机的整体,需要所有器官都健在才可以存在。而实际上组件化的目标之一就是降低整体(app)与器官(组件)的依赖关系,缺少任何一个器官app都是可以存在并正常运行的。

    ·头和胳膊可以单独存在吗?左图也没有说明白,其实答案应该是肯定的。每个器官(组件)可以在补足一些基本功能之后都是可以独立存活的。这个是组件化的第二个目标:组件可以单独运行。

    ·组件化和插件化可以都用右图来表示吗?如果上面两个问题的答案都是YES的话,这个问题的答案自然也是YES。每个组件都可以看成一个单独的整体,可以按需的和其他组件(包括主项目)整合在一起,从而完成的形成一个app

    ·右图中的小机器人可以动态的添加和修改吗?如果组件化和插件化都用右图来表示,那么这个问题的答案就不一样了。对于组件化来讲,这个问题的答案是部分可以,也就是在编译期可以动态的添加和修改,但是在运行时就没法这么做了。而对于插件化,这个问题的答案很干脆,那就是完全可以,不论实在编译期还是运行时!

    ·本文主要集中讲的是组件化的实现思路,对于插件化的技术细节不做讨论,我们只是从上面的问答中总结出一个结论:组件化和插件化的最大区别(应该也是唯一区别)就是组件化在运行时不具备动态添加和修改组件的功能,但是插件化是可以的。

    ·暂且抛弃对插件化“道德”上的批判,我认为对于一个Android开发者来讲,插件化的确是一个福音,这将使我们具备极大的灵活性。但是苦于目前还没有一个完全合适、完美兼容的插件化方案(RePlugin的饥饿营销做的很好,但还没看到疗效),特别是对于已经有几十万代码量的一个成熟产品来讲,套用任何一个插件化方案都是很危险的工作。所以我们决定先从组件化做起,本着做一个最彻底的组件化方案的思路去进行代码的重构,下面是最近的思考结果,欢迎大家提出建议和意见。

    以上是专业的解答,我看后的理解是,组件化就是将app划分为多个独立的功能,每个功能都能通过调试安装在手机上。每个独立的组件是互不影响的,当所有组件合并在一起就是一个完整的app。这种组件化的方式适合多人协同开发,互不影响,而且进度上也不用等其他人完成。

    二、如何实现组件化

    1.代码解耦使用android studio在程序中创建module目录,每个module用library的样式创建。分为两种类型,一种是library依赖库,将app公共部分的类,参数和第三方库放在里面,另一种component是一个完整功能模块,也就是我们将功能组件化后的产物。

    2.组件的单独调试

    上面说过,每个组件分离出来后都是一个完整的功能模块,是可以进行调试安装的。首先需要在每个模块下面的gradle.properties中定义变量isRunAlone = true,在build.gradle头部加入:

    if(isRunAlone.toBoolean()){

    apply plugin: 'com.android.application'   //isRunAlone为true时,进行单独开发调试

    }else{

    apply plugin: 'com.android.library'   //isRunAlone为false时,合并成一个项目

    }

    在app项目下也需要定义gradle.properties中定义变量isRunAlone = true,在build.gradle的dependencies标签下加入:

    if (!isRunAlone.toBoolean()){

    compile project(':imagecomponent')  //isRunAlone为false时,将组件加入到应用中

    compile project(':textcomponent')

    }

    3.组件间的调用和传输

    组件间的调用可以有好几种方式,这里我讲下阿里巴巴的页面路由框架Arouter,它的集成可以有效的解决调用和数据传输。https://github.com/alibaba/ARouter    github网址

    典型应用

    从外部URL映射到内部页面,以及参数传递与解析

    跨模块页面跳转,模块间解耦

    拦截跳转过程,处理登陆、埋点等逻辑

    跨模块API调用,通过控制反转来做组件解耦

    我主要讲下基础功能:

    1.添加依赖和配置

    dependencies {

    //替换成最新版本,需要注意的是api

    //要与compiler匹配使用,均使用最新版可以保证兼容

    compile 'com.alibaba:arouter-api:x.x.x'

    annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'

    ...

    }

    2.添加注解

    在你需要调用的组件入口类的顶部加入注解:

    //在支持路由的页面上添加注解(必选)

    //这里的路径需要注意的是至少需要有两级,/xx/xx

    @Route(path = "/test/activity")

    public class YourActivity extend Activity {

    ...

    }

    3.初始化SDK

    一般在app项目的application的oncreate方法中初始化。

    if (isDebug()) {           //这两行必须写在init之前,否则这些配置在init过程中将无效

    ARouter.openLog();     //打印日志

    ARouter.openDebug();   //开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)

    }

    ARouter.init(mApplication); //尽可能早,推荐在Application中初始化

    4.发起路由操作

    // 1.应用内简单的跳转(通过URL跳转在'进阶用法'中)

    ARouter.getInstance().build("/test/activity").navigation();

    // 2.跳转并携带参数

    ARouter.getInstance().build("/test/1")

    .withLong("key1", 666L)

    .withString("key3", "888")

    .withObject("key4", new Test("Jack", "Rose"))

    .navigation();

    接收带参数的跳转使用getIntent.getString(“key3”,””);这种方式接收。

    注意:各模块下build.gradle的defaultConfig标签下需加入:

    javaCompileOptions {

    annotationProcessorOptions {

    arguments = [ moduleName : project.getName() ]

    }

    }

    相关文章

      网友评论

          本文标题:android 组件化

          本文链接:https://www.haomeiwen.com/subject/wdjxpxtx.html