美文网首页
使用编译时注解实现 把微信支付模块 单独做成一个 module

使用编译时注解实现 把微信支付模块 单独做成一个 module

作者: cao苗子 | 来源:发表于2019-10-21 11:43 被阅读0次

    大家在做微信支付的时候是不是都是在主app中的创建wxapi这个包,所有的微信支付逻辑都是在app中写?当业务逻辑越来越多或是哪天要把支付模块砍掉呢?怎么做,最好还是把它单独做成一个module的形式!添加依赖就行。

    1.添加依赖

    app中

      implementation project(path: ':pay_annotations')
        implementation project(path: ':miaozi_pay')
        annotationProcessor project(path: ':pay_compiler')
    

    在pay_compiler中 添加一下依赖

    apply plugin: 'java-library'
    
    dependencies {
    
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    
        implementation 'com.google.auto.service:auto-service:1.0-rc6'
        annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6'
        implementation 'net.ltgt.gradle.incap:incap-processor:0.2'
        implementation 'com.squareup:javapoet:1.11.1'
        implementation project(path: ':pay_annotations')
    
    }
    tasks.withType(JavaCompile){
        options.encoding='UTF-8'
    }
    sourceCompatibility = "7"
    targetCompatibility = "7"
    
    

    要在app中创建一个BaseApplication,在这里执行的时候生成WXPayEntryActivity

    /**
     * created by panshimu
     * on 2019/10/21
     */
    @WXPayEntry(packageName = "com.miaozi.android_data06",entryClass = BaseWXPayActivity.class)
    public class BaseApplication extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
        }
    }
    

    !!!注意的一点是 pay_annotations 和 pay_complier是一个java lib。而miaozi_pay是android lib。
    在pay_annotaions中新建WXPayEntry

    @Retention(RetentionPolicy.CLASS)
    @Target(ElementType.TYPE)
    public @interface WXPayEntry {
        String packageName();
        Class<?> entryClass();
    }
    

    代码生成工具类 Processor

    package com.miaozi.pay_compiler;
    
    import com.google.auto.service.AutoService;
    import com.miaozi.pay_annotations.WXPayEntry;
    
    import java.lang.annotation.Annotation;
    import java.util.LinkedHashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import javax.annotation.processing.AbstractProcessor;
    import javax.annotation.processing.Filer;
    import javax.annotation.processing.ProcessingEnvironment;
    import javax.annotation.processing.Processor;
    import javax.annotation.processing.RoundEnvironment;
    import javax.lang.model.SourceVersion;
    import javax.lang.model.element.AnnotationMirror;
    import javax.lang.model.element.AnnotationValue;
    import javax.lang.model.element.AnnotationValueVisitor;
    import javax.lang.model.element.Element;
    import javax.lang.model.element.ElementVisitor;
    import javax.lang.model.element.ExecutableElement;
    import javax.lang.model.element.TypeElement;
    
    /**
     * created by panshimu
     * on 2019/10/21
     */
    @AutoService(Processor.class)
    public class PayProcessor extends AbstractProcessor {
        private Filer mFiler;
        @Override
        public synchronized void init(ProcessingEnvironment processingEnvironment) {
            super.init(processingEnvironment);
            mFiler = processingEnvironment.getFiler();
        }
    
        @Override
        public SourceVersion getSupportedSourceVersion() {
            return SourceVersion.latestSupported();
        }
        /**
         * 需要处理的 Annotation
         * @return
         */
        @Override
        public Set<String> getSupportedAnnotationTypes() {
            Set<String> types = new LinkedHashSet<>();
            for (Class<? extends Annotation> annotation : getSupportedAnnotations()) {
                types.add(annotation.getCanonicalName());
            }
            return types;
        }
        private Set<Class<? extends Annotation>> getSupportedAnnotations() {
            Set<Class<? extends Annotation>> annotations = new LinkedHashSet<>();
            annotations.add(WXPayEntry.class);
            return annotations;
        }
        @Override
        public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
            //生成一个 Class xxx.wxapi.WXEntryActivity extends BaseWXEntryActivity
            generateWXPayCode(roundEnvironment);
            return false;
        }
    
        private void generateWXPayCode(RoundEnvironment roundEnvironment) {
            WXEntryElementVisitor visitor = new WXEntryElementVisitor();
            visitor.setFiler(mFiler);
            scanElement(roundEnvironment,WXPayEntry.class,visitor);
        }
    
        private void scanElement(RoundEnvironment roundEnvironment, Class<? extends Annotation> annotations, AnnotationValueVisitor visitor){
            Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(annotations);
            for (Element element : elements) {
                List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
                for (AnnotationMirror annotationMirror : annotationMirrors) {
                    Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = annotationMirror.getElementValues();
                    for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : elementValues.entrySet()) {
                        entry.getValue().accept(visitor,null);
                    }
                }
            }
        }
    }
    

    WXEntryElementVisitor

    package com.miaozi.pay_compiler;
    
    import com.squareup.javapoet.JavaFile;
    import com.squareup.javapoet.TypeName;
    import com.squareup.javapoet.TypeSpec;
    
    import java.io.IOException;
    
    import javax.annotation.processing.Filer;
    import javax.lang.model.element.Modifier;
    import javax.lang.model.type.TypeMirror;
    import javax.lang.model.util.SimpleAnnotationValueVisitor7;
    
    /**
     * created by panshimu
     * on 2019/10/21
     */
    public class WXEntryElementVisitor extends SimpleAnnotationValueVisitor7<Void,Void> {
        private String mPackageName;
        private TypeMirror mTypeMirror;
        private Filer mFiler;
        @Override
        public Void visitString(String s, Void aVoid) {
            mPackageName = s;
            return aVoid;
        }
    
        @Override
        public Void visitType(TypeMirror typeMirror, Void aVoid) {
            mTypeMirror = typeMirror;
            generateWXPayCode();
            return aVoid;
        }
        public void setFiler(Filer filer){
            this.mFiler = filer;
        }
    
        /**
         * 生成类
         */
        private void generateWXPayCode() {
            //xxx.wxapi.WXEntryActivity extends BaseWXEntryActivity
            TypeSpec.Builder classTypeSpec = TypeSpec.classBuilder("WXPayEntryActivity")
                    .addModifiers(Modifier.PUBLIC,Modifier.FINAL)
                    .superclass(TypeName.get(mTypeMirror));
            try {
                JavaFile.builder(mPackageName+"wxapi",classTypeSpec.build())
                        .addFileComment("微信支付自动生成")
                        .build().writeTo(mFiler);
            } catch (IOException e) {
                e.printStackTrace();
                LogUtil.show("微信支付自动生成代码报错啦");
            }
    
    
        }
    }
    
    

    2.微信支付业务逻辑处理类 BaseWXPayActivity

    实现继承 WXPayActivity
    这个是在miaozi_pay中。所有的支付模块都在这里做处理。

    /**
     * created by panshimu
     * on 2019/10/21
     */
    public class BaseWXPayActivity extends WXPayActivity{
        //在这里处理微信支付业务
    }
    

    3.生成的代码

    image.png

    好了,就这样了。正常的在清单文件注册就行。报红也是可以打包的。没有事 哈哈哈哈

    源码走起来!!!
    https://github.com/panshimu/Android_Data06

    有问题请留言。

    相关文章

      网友评论

          本文标题:使用编译时注解实现 把微信支付模块 单独做成一个 module

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