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

2019-10-21  本文已影响0人  cao苗子

大家在做微信支付的时候是不是都是在主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

有问题请留言。

上一篇下一篇

猜你喜欢

热点阅读