Android注解组件化方案

1 篇文章 0 订阅
1 篇文章 0 订阅

注解组件化方案:https://github.com/luiing/Assignor

目前市面上的组件化方案原理:scheme,代码注入Aop,代码生成等;

本方案利用注解处理器生成代码,优点是简单便捷,集成方便;

原理:注解Test.class为abc,在注解处理器运行时生成一个java源文件abcGenerate.java,里面包含了被注解类的无参对象Object abc=new Test(),在调用abc组件时,通过反射方法取到生成的变量abc,剩下的就是调用该类的方法。

1. 创建注解类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface BindCall {
    String value() default "";
}

2. 注解处理器实现,注解处理器在编译前运行

增加文件:resources/META-INF/services/javax.annotation.processing.Processor
内容为注解处理器全包名:com.uis.call.BindCallProcessor
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes({"com.uis.call.BindCall"})
public class BindCallProcessor extends AbstractProcessor {

    Filer filer;
    Messager messager;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        filer = processingEnvironment.getFiler();
        messager = processingEnvironment.getMessager();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
            for (Element element : roundEnvironment.getElementsAnnotatedWith(BindCall.class)) {
                if(element.getKind() == ElementKind.CLASS) {
                    String clsName = element.getAnnotation(BindCall.class).value();
                    System.out.println("---CallProcessor name="+element.getSimpleName()+",value="+clsName);
                    if(clsName.isEmpty() || !clsName.matches("[a-zA-Z_]\\w*")){
                        System.out.println("---CallProcessor generate fail:"+clsName+" is not java class name");
                    }else{
                        createJavaFile(clsName,element);
                    }
                }
            }
        return false;
    }

    private void createJavaFile(String clsName,Element element) {
        try {
            String pkgName = BindCallUtils.generatePkg;
            String extName = clsName + BindCallUtils.generate;
            JavaFileObject javaFile = filer.createSourceFile(pkgName+"."+extName);
            BufferedWriter writer = new BufferedWriter(javaFile.openWriter());
            writer.write("package "+pkgName+";\n\n");
            writer.write("public class "+extName+"{\n\n");
            writer.write("    public final Object "+clsName+" = new "+element.toString()+"();\n\n");
            writer.write("}\n");
            writer.flush();
            writer.close();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }
}

3. 组件调用核心代码

public class BindCallUtils {

    public  static String generatePkg = "a.b.c.d.generate";
    public  static String generate = "Generate";
    //找到注解处理器生成的field
    public static Object getCallValue(String bindName){
        String clsName = generatePkg + "." + bindName + generate;
        try {
            Class<?> cls = Class.forName(clsName);
            Field field = cls.getField(bindName);
            field.setAccessible(true);
            return field.get(cls.newInstance());
        }catch (Throwable ex){
            System.out.println("------ Not found "+clsName+" ------");
        }
        return null;
    }
}
        public Result call(){
            ICall call = getCall();
            if(call != null){
                return call.onCall(param);
            }
            return newResult(param.id).error(404,"Not found "+param.callName).build();
        }

        public void call(IResult result){
            final ICall call = getCall();
            sResult.put(param.id,result);
            if(call != null){
                Worker.ioExecute(new Function0<Unit>() {
                    @Override
                    public Unit invoke() {
                        call.onCallback(param);
                        return null;
                    }
                });
            }else{
                newResult(param.id).error(404,"Not found "+param.callName).build();
            }
        }

        private ICall getCall(){
            ICall call = null;
            if(!TextUtils.isEmpty(param.callName)) {
                WeakReference<ICall> ref = sCall.get(param.callName);
                if (ref != null) {
                    call = ref.get();
                }
                if (call == null) {
                    Object value = BindCallUtils.getCallValue(param.callName);
                    if (value != null) {
                        call = (ICall) value;
                        sCall.put(param.callName, new WeakReference<>(call));
                    }
                }
            }
            return call;
        }

4.组件实现和使用

@BindCall("Test")
public class CoupleTest extends SimpleCall {
    @Override
    public void onCallback(Call.Params param) {
        SystemClock.sleep(2000);
        Call.newResult(param.id).success().addParam("name",param.toString()).build();
    }

    @Override
    public Call.Result onCall(Call.Params param) {

        return Call.newResult(param.id).success().addParam("name",param.toString()).build();
    }
}


Call.Result result = Call.newParams("Test")
                    .setAction("a")
                    .addParam("key","111")
                    .call();
ALog.e(result.toString());
Call.newParams("Test")
                    .setAction("b")
                    .addParam("key","222").call(new IResult() {
                @Override
                public void onResult(Call.Result result) {
                    ALog.e(result.toString());
                }
            });

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值