前言
Android对接微信登录和支付几乎是现在所有的商用Android APP都需要做的一个东西,不过每次开发我们都需要去新建微信官方要求的指定包名+Activity名字,这个还是有点烦的。下面我将通过 APT 封装一个可以绕过微信包名限制的微信登录和支付功能。(其实也不算是真的绕过啦)
最终效果
先上最后封装好我调用起微信登录的代码:
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
WeChatAPI.getInstance().setSingInCallBack(new IWXSignCallBack() {
@Override
public void signSuccess(String info) {
Toast.makeText(MainActivity.this, "info: " + info, Toast.LENGTH_SHORT).show();
}
}).signIn();
}
});
}
}
效果还可以吧,只需要加入几行代码就可以调起微信登录 。
原理
这里用到的和 ButterKnife 一样的技术叫做编译时注解的技术即 APT ,代码在编译时会扫描AbstractProcessor的所有子类,并且调用这些子类的process函数,在这个函数就会将所有的代码元素传递进来。此时我们只需要在这个process函数中获取所有添加了某个注解的元素,然后对这些元素进行操作,使之能够满足我们的需求,这样我们就可以在编译期对源代码进行处理,例如生成新的类等。在运行时,我们通过一些接口对这些新生成的类进行调用以此完成我们的功能。
emmmmm 很抽象,其实我也觉得挺抽象的,我们直接看代码吧~
代码
代码我们分出两块讲: 通过 APT 生成 WXEntryActivity 文件 以及 对接微信SDK;
通过 APT 生成 WXEntryActivity 文件
我们封装这个东西就是为了方便还有通用性,我们用了组件化的思想,用两个 Module 完成我们这个功能所以我们要新建两个 Java Library 的 Module 分别为:annotation(放注解类),compile (放对注解类的处理)。
- 新建Module
新建两个 Java Library 分别为: annotation( 放注解类 ),compile ( 放对注解类的处理)。
注意:这里新建 Java Library 而不是 Android Library 是因为我们的注解这里其实会用到很多标准 Java SDK的一些注解类。其中一些是 Android Library 里面没有”。
画面效果不好,意思意思就行了
- 添加依赖
在 annotation Module 的 gradle 文件中添加支持中文的依赖
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//添加支持中文
tasks.withType(JavaCompile){
options.encoding='UTF-8'
}
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
在 compile Module 的 gradle 中添加一下依赖
apply plugin: 'java-library'
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
api project(':annotation')
//生成 java library 的一个工具
api 'com.squareup:javapoet:1.10.0'
//注解 processor 类并生成 META-INF 的配置信息
api 'com.google.auto.service:auto-service:1.0-rc4'
annotationProcessor'com.google.auto.service:auto-service:1.0-rc4'
//添加支持中文
tasks.withType(JavaCompile){
options.encoding='UTF-8'
}
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
- 创建微信登录注解类
在 annotations Module 下创建 EntryGeneral 注解
@Target(ElementType.TYPE)//作用于类和接口
@Retention(RetentionPolicy.SOURCE)//只在源码阶段
public @interface EntryGeneral {
String packageName();
//要继承的类
Class<?> entryTemplete();
}
- 写一个 AbstractProcessor 的子类
在 compile Module 下写一个 AbstractProcessor 的子类并添加我们的注解元素,对注解元素进行扫描操作然后再生成我们指定包名下的指定名文件。
注意:这里要记得在 compile Module 下的依赖文件引入 annotation Module
@AutoService(Processor.class)
public class WeChatProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
//扫描注解并生成我们的微信登录入口文件
generateEntryCode(roundEnvironment);
return false;
}
//设置为最大版本
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
/**
* 获取到注解的名字
*
* @return Set
*/
@Override
public Set<String>