美文网首页大牛的文章
【Android】注解框架(四)-- 一行代码注入微信支付

【Android】注解框架(四)-- 一行代码注入微信支付

作者: 指间沙似流年 | 来源:发表于2018-01-18 10:40 被阅读515次

    目录

    1. 【Android】注解框架(一)-- 基础知识Java 反射
    2. 【Android】注解框架(二)-- 基础知识(Java注解)& 运行时注解框架
    3. 【Android】注解框架(三)-- 编译时注解,手写ButterKnife
    4. 【Android】注解框架(四)-- 一行代码注入微信支付

    微信一般处理方式

    通常情况下当我们接入微信的时候,微信会蛋疼的让我们在我们的包下侵入式的添加wxapi包,在这个包下面处理支付的相关业务逻辑。

    image

    这个样子就非常蛋疼了,不谈看着难受,就连我们自己的项目规则都被他给打乱了,那么有什么好的办法来解决这个问题呢?

    其实用我们上次学到的AnnotationProcessor就可以解决这个问题。

    我们通过apt来自动生成包名.wxapi.WXPAYEntryActivity并让这个文件继承我们自己写的WXPayActivity,我们在WXPayActivity中来处理微信支付的逻辑,这样WXPayActivity就可以写在我们自己定义的模块下面了,不仅仅局限于app,组件化的module中都可以写,当我们需要接入的时候直接饮用module并直接自动生成包名.wxapi.WXPAYEntryActivity就可以了。

    实现

    首先我们看下架构图,大概就是下面这个样子:

    image
    1. 生成各个module

      app - 主项目
      wx_pay - android lib
      wx_annotaion - java lib
      wx_compiler - java lib
      
    2. wx_annotaion

      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.CLASS)
      public @interface WXPayEntry {
      
          // 包名
          String packageName();
      
          // 类名
          Class<?> entryClass();
      }
      
    3. wx_pay

      这边写我们自己的微信支付相关的代码

      public class WXPayActivity extends AppCompatActivity implements IWXAPIEventHandler {
          @Override
          public void onReq(BaseReq baseReq) {
      
          }
      
          @Override
          public void onResp(BaseResp baseResp) {
      
          }
      }
      
    4. wx_compiler

      java api : http://www.yq1012.com/api/index.html-overview-summary.html

      visitor不懂的自定查看:javax.lang.model.util.SimpleAnnotationValueVisitor6

      // WXEntryProcessor.class
      @AutoService(Processor.class)
      public class WXEntryProcessor extends AbstractProcessor {
      
          private Filer filer;
      
          @Override
          public synchronized void init(ProcessingEnvironment processingEnvironment) {
              super.init(processingEnvironment);
              filer = processingEnvironment.getFiler();
          }
      
          @Override
          public Set<String> getSupportedAnnotationTypes() {
              Set<String> types = new LinkedHashSet<>();
              Set<Class<? extends Annotation>> supportedAnnotations = getSupportedAnnotations();
              for (Class<? extends Annotation> supportedAnnotation : supportedAnnotations) {
                  types.add(supportedAnnotation.getCanonicalName());
              }
              return types;
          }
      
          private Set<Class<? extends Annotation>> getSupportedAnnotations() {
              Set<Class<? extends Annotation>> annotations = new LinkedHashSet<>();
              annotations.add(WXPayEntry.class);
              return annotations;
          }
      
          @Override
          public SourceVersion getSupportedSourceVersion() {
              return SourceVersion.latestSupported();
          }
      
          @Override
          public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
              generateWXPayCode(roundEnvironment);
      
              return false;
          }
      
          private void generateWXPayCode(RoundEnvironment roundEnvironment) {
              WXPayEntryVisitor visitor = new WXPayEntryVisitor();
              visitor.setFiler(filer);
              scan(visitor, roundEnvironment, WXPayEntry.class);
          }
      
          private void scan(WXPayEntryVisitor visitor,
                            RoundEnvironment roundEnvironment,
                            Class<? extends Annotation> annotation) {
      
              Set<? extends Element> elementsAnnotatedWith = roundEnvironment.getElementsAnnotatedWith(annotation);
              for (Element element : elementsAnnotatedWith) {
                  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);
                      }
                  }
              }
      
          }
      }
      
      // WXPayEntryVisitor
      public class WXPayEntryVisitor extends SimpleAnnotationValueVisitor7<Void, Void> {
      
          private String packageName;
          private TypeMirror typeMirror;
          private Filer filer;
      
          public WXPayEntryVisitor setFiler(Filer filer) {
              this.filer = filer;
              return this;
          }
      
          @Override
          public Void visitString(String s, Void aVoid) {
              this.packageName = s;
              return aVoid;
          }
      
          @Override
          public Void visitType(TypeMirror typeMirror, Void aVoid) {
              this.typeMirror = typeMirror;
              generateWXPayCode();
              return aVoid;
          }
      
          private void generateWXPayCode() {
              // Class xxx.wxapi.WXPayEntryActivity extends WXPayActivity
              TypeSpec.Builder classSpecBuilder = TypeSpec.classBuilder("WXPayEntryActivity")
                      .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                      .superclass(TypeName.get(typeMirror));
      
              try {
                  JavaFile.builder(packageName + ".wxpai", classSpecBuilder.build())
                          .build().writeTo(filer);
              } catch (IOException e) {
                  e.printStackTrace();
                  System.out.println(e);
              }
          }
      }
      
    5. 使用

      在baseApplication中使用注解

      @WXPayEntry(packageName = "com.fastaoe.wxannotationprocessordemo", 
          entryClass = WXPayActivity.class)
      public class BaseApplication extends Application {
      }
      

      此时重新build我们的工程就生成了符合要求的WXPayEntryActivity

      image

    相关文章

      网友评论

        本文标题:【Android】注解框架(四)-- 一行代码注入微信支付

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