美文网首页
路由工具ARouter和CC对比:CC

路由工具ARouter和CC对比:CC

作者: Allenlll | 来源:发表于2019-08-13 17:46 被阅读0次

    CC

    配置

    • app中build.gradle配置
    ext.mainApp = true//标明是主app
    apply from :rootProject.file('cc-settings-2.gradle')//配置文件,集成了公共的引用
    
      addComponent 'component_a' ,project (':component_a')
    //引用,这样写是为了,子Module单独运行时,可以不用修改这里,只需要在工程根目录的local.properties添加如下配置,并重新打包运行主app
    //module_name=true #module_name为具体每个module的名称,设置为true代表从主app的依赖列表中排除该组件module
        addComponent 'component_b' ,project(':component_b')
        addComponent 'component_jsbridge' ,project(':component_jsbridge')
    
    • 普通的Module中build.gradle
    ext.alwaysLib = true//标明只是普通module,不会被当作app运行
    apply from :rootProject.file('cc-settings-2.gradle')
    
    • 可运行的module中的build.gradle
    apply from: rootProject.file('cc-settings-2.gradle')
    android {
        defaultConfig {
            if (project.ext.runAsApp) {
                applicationId "com.sohu.hy.ccrouter.component.jsbridge"
            }
        }
       resourcePrefix "component_jsbridge_"//可选,为了资源不冲突
    }
    

    想要module可运行,还需要在main目录下建立debug目录,新建LauncherActivity和Application。

    • 根目录build.gradle
    buildscript {
        dependencies {
            classpath 'com.android.tools.build:gradle:3.4.0'
            classpath 'com.billy.android:cc-register:1.1.1' //使用最新版,自动注册插件,自动插入需要的代码
        }
    }
    
    • cc-settings-2.gradle
    apply plugin :'cc-register'//应用自动插入代码的插件
    
    dependencies {
        implementation project(':component_base')//都需要引用的正常module
        api "com.billy.android:cc:2.1.5"//都需要引用的cc api
        //添加全局拦截器
        if (project.ext.has('runAsApp') && project.ext.runAsApp) {
            implementation project(':demo_interceptors')
        }
    }
    //开启app内部多进程组件调用时启用下面这行代码
    ccregister.multiProcessEnabled = true
    
    //开启app内部多进程组件调用时,可以启用下方的配置排除一些进程
    //ccregister.excludeProcessNames = [':pushservice', ':processNameB']
    
    //按照如下格式添加自定义自动生成代码的信息,可添加多个(也可每次add一个,add多次)
    ccregister.registerInfo.add([
            //在自动注册组件的基础上增加:自动注册组件B的processor
            'scanInterface'             : 'com.sohu.hy.component_b.process.IActionProcessor'
            , 'codeInsertToClassName'   : 'com.sohu.hy.component_b.ComponentB'
            , 'codeInsertToMethodName'  : 'initProcessors'
            , 'registerMethodName'      : 'add'
    ])
    
    

    使用

    • 初始化
       CC.enableVerboseLog(true)
            CC.enableDebug(true)
            CC.enableRemoteCC(true)//开启跨进程调用,子module可单独运行时需要开启
    
    • module独立运行。
      要显示界面时,还需要设置额外的Application,LauncherActivity。更新完module,运行app,是新的代码。主app不能包含此组件,local.properties里面加上module名称,要不然会找主app的引用,而不会找这个独立运行的module。为什么要独立运行module?只在module上面开发,主app来调用。最大作用缩小编译时间,主app也能调用。
    • component 组件对外接口,根据名称找到接口,根据不同action执行不同的操作
    //同步调用,直接返回结果
    CCResult result = CC.obtainBuilder("ComponentA")
            .setActionName("showActivity")
            .build()
            .call();
    //或 异步调用,不需要回调结果
    String callId = CC.obtainBuilder("ComponentA")
            .setActionName("showActivity")
            .build()
            .callAsync();
    //或 异步调用,在子线程执行回调
    String callId = CC.obtainBuilder("ComponentA")
            .setActionName("showActivity")
            .build()
            .callAsync(new IComponentCallback() {
                @Override
                public void onResult(CC cc, CCResult result) {
                    //此onResult在子线程中运行
                }
            });
    //或 异步调用,在主线程执行回调
    String callId = CC.obtainBuilder("ComponentA")
            .setActionName("login")
            .build()
            .callAsyncCallbackOnMainThread(new IComponentCallback() {
                @Override
                public void onResult(CC cc, CCResult result) {
                    //此onResult在主线程中运行
                    String toast = "login " + (result.isSuccess() ? "success" : "failed");
                    Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show();
                }
            });
    

    定义组件时,onCall方法的返回值,return true,代表异步执行,在未来某个时间会调用CC.sendResult,返回false代表同步调用,return false 之前调用CC.sendResult。
    CC.sendResult每个action必须执行。CC.obtainBuilder(componentName)可异步可同步执行。

    • IActionProcessor,自定义action处理类
    interface  IActionProcessor{
        fun getActionName():String
    
        /**
         * action的处理类
         * @param cc cc
         * @return 是否异步调用 [CC.sendCCResult] . true:异步, false:同步调用
         */
        abstract fun onActionCall(cc: CC): Boolean
    }
    

    利用插件auto-register来处理action,避免if else的分支,往某个类中某个方法中添加一些语句,固定的写法。
    配置方法:

         ccregister.registerInfo.add([
             //在自动注册组件的基础上增加:自动注册组件B的processor
             'scanInterface'             : 'com.sohu.hy.component_b.process.IActionProcessor'
             , 'codeInsertToClassName'   : 'com.sohu.hy.component_b.ComponentB'
             , 'codeInsertToMethodName'  : 'initProcessors'
             , 'registerMethodName'      : 'add'
         ])
    
    public class ComponentB implements IComponent, IMainThread {
    
        private AtomicBoolean initialized = new AtomicBoolean(false);
        private final HashMap<String, IActionProcessor> map = new HashMap<>(4);
    
        private void initProcessors() {
            add(new CheckAndLoginProcessor());
            add(new LoginProcessor());
            add(new GetDataProcessor());
        }
    
        private void add(IActionProcessor processor) {
            map.put(processor.getActionName(), processor);
        }
    
    • IMainThread
      指定某些action的oncall方法回调时的线程。打破默认的线程调用状态。需要注意和onCall返回值的异同,onCall返回值只是标记是否立即调用CC.sendResult。
    /**
     * 指定是否在主线程运行
     * @author billy.qi
     * @since 18/9/19 11:31
     */
    public interface IMainThread {
        /**
         * 根据当前actionName确定组件的{@link IComponent#onCall(CC)} 方法是否在主线程运行
         * @param actionName 当前CC的action名称
         * @param cc 当前CC对象
         * @return 3种返回值: <br>
         *              null:默认状态,不固定运行的线程(在主线程同步调用时在主线程运行,其它情况下在子线程运行)<br>
         *              true:固定在主线程运行<br>
         *              false:固定子线程运行<br>
         */
        Boolean shouldActionRunOnMainThread(String actionName, CC cc);
    }
    
    
    • IParamJsonConverter跨进程传递自定义类型,Json的转换类。

    • ICCInterceptor
      可以用业修改参数,修改结果或者中断执行

    public interface ICCInterceptor {
        /**
         * 拦截器方法
         * chain.getCC() 来获取cc对象
         * 调用chain.proceed()来传递调用链
         * 也可通过不调用chain.proceed()来中止调用链的传递
         * 通过cc.getParams()等方法来获取参数信息,并可以修改params
         * @param chain 链条
         * @return 调用结果
         */
        CCResult intercept(Chain chain);
    }
    //增加拦截器
    CC.obtainBuilder("componentName")
        .setActionName("actionName")
        .addInterceptor(new MyInterceptor())
        .build()
        .call();
    
    • ICCGlobalInterceptor
      每次调用都会执行,实现接口后,auto-register会自动注册。
    • IDynamicComponent
      动态组件,不会自动注册,而IComponent会自动注册。
    CC.registerComponent(dyComponent)
    CC.unregisterConponent(dyComponent)
    
    • 多进程
    *   无注解 : 该组件类在主进程中运行
    *   @SubProcess(":web") : 该组件类运行在packageName:web子进程,
    *   @AllProcess : 该组件类在App内所有进程中都存在一个对象,调用该组件时,调用的是调用方所在进程中的组件类对象
        @AllProcess注解可用于在多进程环境下提供:在调用方所在进程中创建自定义Fragment/View等对象的服务
    

    异同

    • 跳转页面时传递参数,获取方式不同,使用getNavigateParam,不能为页面自动赋值。
    • cc可以异步请求,并返回传递丰富的数据类型,不公限于执行页面跳转,任何任务都可以执行,并获取返回结果。一个component就是一个处理任务的工厂。
    • CC类似http请求,一对一主动调用,并有回调,可同步可异步。利用动态组件可以实现任务的接收与回调

    相关文章

      网友评论

          本文标题:路由工具ARouter和CC对比:CC

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