组件化 3 -- 整体工作流程、调用其它模块功能

围巾🧣 2024年03月22日 220次浏览

工作流程

应用注解

编译时 arouter_compiler

  • ARouterProcessor 扫描注解

  • 封装 RouterBean

  • 根据应用类的类型确定TypeMirror

  • 生成对应 Path、Group 的 Class,例如 ARouter$$Group$$order,ARouter$$Path$$order

  • ARouter$$Group$$order 保存 group 对应的 path

    public Map<String, Class<? extends ARouterPath>> getGroupMap() {
    Map<String, Class<? extends ARouterPath>> groupMap = new HashMap<>();
    groupMap.put("order", ARouter$$Path$$order.class);
    return groupMap;
    }
    
  • ARouter$$Path$$order 保存该组全部 path 对应的 class 关系

    public Map<String, RouterBean> getPathMap() {
    Map<String, RouterBean> pathMap = new HashMap<>();
    pathMap.put("/order/getOrderBean", RouterBean.create(RouterBean.TypeEnum.CALL, OrderAddressImpl.class, "/order/getOrderBean", "order"));
    pathMap.put("/order/getDrawable", RouterBean.create(RouterBean.TypeEnum.CALL, OrderDrawableImpl.class, "/order/getDrawable", "order"));
    pathMap.put("/order/getUserInfo", RouterBean.create(RouterBean.TypeEnum.CALL, OrderUserImpl.class, "/order/getUserInfo", "order"));
    pathMap.put("/order/Order_MainActivity", RouterBean.create(RouterBean.TypeEnum.ACTIVITY, Order_MainActivity.class, "/order/Order_MainActivity", "order"));
    return pathMap;
    }
    

使用 RouterManager 跳转

  • 根据传入路径拆分 group、记录 group和path
  • 寻找 ARouterGroup(ARouter$$Group$$order)、缓存
  • 根据 ARouterGroup 寻找 ARouterPath(ARouter$$Path$$order)
  • 在 ARouterPath 根据 path 寻找 RouterBean
  • 根据 RouterBean 的信息去跳转或者返回调用接口

参数如何传递,赋值(getParameter)

arouter_annotation 模块定义 Parameter 注解

@Target(ElementType.FIELD) // 该注解作用在类之上 字段上有作用
@Retention(RetentionPolicy.CLASS) // 要在编译时进行一些预处理操作,注解会在class文件中存在
public @interface Parameter {

    // 不填写name的注解值表示该属性名就是key,填写了就用注解值作为key
    // 从getIntent()方法中获取传递参数值
    String name() default "";
}

Activity 的字段应用 Parameter

编译时 arouter_compiler

  • ParameterProcessor扫描注解

  • 利用工厂 ParameterFactory 构建生成类的内容,该类主要就是一个方法 getParameter

  • 在bundle里取出对应值赋到字段上即可

    // 取到 activity,包含强化转
    public void addFirstStatement() {
        method.addStatement("$T t = ($T) " + ProcessorConfig.PARAMETER_NAME, className, className);
    }
    
    // 取值赋值,因为有多种类型,需细心分多类型判断
    /** 多行 循环 复杂
     * 构建方体内容,如:t.s = t.getIntent.getStringExtra("s");
     * @param element 被注解的属性元素
     */
    public void buildStatement(Element element) {
        // 遍历注解的属性节点 生成函数体
        TypeMirror typeMirror = element.asType();
    
        // 获取 TypeKind 枚举类型的序列号
        int type = typeMirror.getKind().ordinal();
    
        // 获取属性名  name  age  sex
        String fieldName = element.getSimpleName().toString();
    
        // 获取注解的值
        String annotationValue = element.getAnnotation(Parameter.class).name();
    
        // 配合: t.age = t.getIntent().getBooleanExtra("age", t.age ==  9);
        // 判断注解的值为空的情况下的处理(注解中有name值就用注解值)
        annotationValue = ProcessorUtils.isEmpty(annotationValue) ? fieldName : annotationValue;
    
        // TODO 最终拼接的前缀:
        String finalValue = "t." + fieldName;
    
        // t.s = t.getIntent().
        // TODO t.name = t.getIntent().getStringExtra("name");
        String methodContent = finalValue + " = t.getIntent().";
    
        // TypeKind 枚举类型不包含String
        if (type == TypeKind.INT.ordinal()) {
            // t.s = t.getIntent().getIntExtra("age", t.age);
            methodContent += "getIntExtra($S, " + finalValue + ")";  // 有默认值
        } else if (type == TypeKind.BOOLEAN.ordinal()) {
            // t.s = t.getIntent().getBooleanExtra("isSuccess", t.age);
            methodContent += "getBooleanExtra($S, " + finalValue + ")";  // 有默认值
        } else  { // String 类型,没有序列号的提供 需要我们自己完成
            // t.s = t.getIntent.getStringExtra("s");
            // typeMirror.toString() java.lang.String
            if (typeMirror.toString().equalsIgnoreCase(ProcessorConfig.STRING)) {
                // String类型
                methodContent += "getStringExtra($S)"; // 没有默认值
            } else if (typeUtils.isSubtype(typeMirror, callMirror)) { // 你居然实现了Call接口
                // t.orderDrawable = (OrderDrawable) RouterManager.getInstance().build("/order/getDrawable").navigation(t);
                methodContent = "t." + fieldName + " = ($T) $T.getInstance().build($S).navigation(t)";
                method.addStatement(methodContent,
                        TypeName.get(typeMirror),
                        ClassName.get(ProcessorConfig.AROUTER_API_PACKAGE, ProcessorConfig.ROUTER_MANAGER),
                        annotationValue);
                return;
            } else { // 对象的传输
                methodContent = "t.getIntent().getSerializableExtra($S)";
            }
        }
    
        // 健壮代码
        if (methodContent.contains("Serializable")) {
            // t.student=(Student) t.getIntent().getSerializableExtra("student");  同学们注意:为了强转
            method.addStatement(finalValue + "=($T)" + methodContent, ClassName.get(element.asType()) ,annotationValue);
        }
        else if (methodContent.endsWith(")")) { // 抱歉  全部的 getBooleanExtra  getIntExtra   getStringExtra
            // 参数二 9 赋值进去了
            // t.age = t.getIntent().getBooleanExtra("age", t.age ==  9);
            method.addStatement(methodContent, annotationValue);
        } else {
            messager.printMessage(Diagnostic.Kind.ERROR, "目前暂支持String、int、boolean传参");
        }
    }
    
  • 生成 ParameterGet 子类

    JavaFile.builder(className.packageName(), // 包名
            TypeSpec.classBuilder(finalClassName) // 类名
                    .addSuperinterface(ClassName.get(parameterType)) //  implements ParameterGet 实现ParameterLoad接口
                    .addModifiers(Modifier.PUBLIC) // public修饰符
                    .addMethod(factory.build()) // 方法的构建(方法参数 + 方法体)
                    .build()) // 类构建完成
            .build() // JavaFile构建完成
            .writeTo(filer); // 文件生成器开始生成类文件
    

在导航时把参数封装到 bundle 里面,用 ParameterManager 管理

Activity 在 onCreate 时调用
ParameterManager.getInstance().loadParameter(this);
调用生成的ParameterGet (Order_MainActivity$$Parameter)类 getParameter 方法赋值

调用其它模块的功能(Call 网络请求、资源res)

基础模块定义功能的 Call 接口

B 模块实现具体逻辑,A 模块要调用其方法

A 模块定义了接口字段

@Parameter(name = "/order/getDrawable")
OrderDrawable orderDrawable; // 公共基础库common

// 拿order模块的 网络请求功能
@Parameter(name = "/order/getOrderBean")
OrderAddress orderAddress;

ParameterProcessor 根据注解自动生成的绑定逻辑:

通过 path 和 RouterManager.navigation(t) 找到具体类并实例化,如

t.orderDrawable = (OrderDrawable) RouterManager.getInstance().build("/order/getDrawable").navigation(t);
t.orderAddress = (OrderAddress) RouterManager.getInstance().build("/order/getOrderBean").navigation(t);

在 Activity 里面调用 ParameterManager.getInstance().loadParameter(this);

自动找到功能的实现类,并实例化对象

直接调用其方法就可使用到其它模块的能力