搭建Android客户端APP架构——《跨组件化路由实现一自动识别生成跳转字符串》
背景说明使用APT技术自动生成跳转字符串常量1.添加arouter-constant模块(JAVA Lib)2.添加生成常量类运行将生成如下常量类
使用常量类demo链接
吐槽
背景
本人从事开发工作也有多年,目前坐标湖南长沙,以前在各种平台也发过一些文章但是都没有坚持下来; 我初步规划是写一个完整的项目系列文章期望能坚持下来。 为什么会想到要写呢? 其一、眨眼就到了而立之年,觉得自己记忆力也是下降久做过的东西总是记不起,果然是好记性不如烂笔头。 其二、这么多年白嫖了网上很多的文章,视频,一直觉得应该分享一些东西但总是沉不下心去做。 其三、可能写的不好至少也留下一些东西,也是希望能帮助到一些朋友。
说明
接上一篇链接: 《跨组件化路由实现一路由跳转》. 上一篇中我们简单实现了组件化路由跳转Activity。 但是我们可以通过ARouter跳转页面,但是其中有一个比较让人觉得不太舒服的地方就是传入值的时候我们必须使用指定的字符串。如果修改,添加我们到处都要修改,这样不太方便。
使用APT技术自动生成跳转字符串常量
在上一个例子的基础上做如下改动
1.添加arouter-constant模块(JAVA Lib)
包名:
com.lyl.arouter.constant
2.添加生成常量类
@Override
public boolean process(Set<? extends TypeElement> typeElements, RoundEnvironment env) {
Set<? extends Element> clazzElement = env.getElementsAnnotatedWith(IsActivity.class);
if (clazzElement != null && clazzElement.size() > 0) {
//构建常量文件
buildARouterConstantFile(clazzElement);
}
return false;
}
//构建常量文件
private void buildARouterConstantFile(Set<? extends Element> clazzElement) {
File savePath = new File("../arouter-constant/src/main/java/com/lyl/arouter/constant/ARouterConstant.java");
if (savePath.exists()) {
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(savePath);
FileChannel inputStreamFileChannel = fileInputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024 * 100);
inputStreamFileChannel.read(buffer);
buffer.flip();
String data = decode(buffer);
System.out.println("inputStreamFileChannel:" + data);
String[] oldFiled = data.split("\n");
List<String> newFiled = new ArrayList();
for (Element object : clazzElement) {
String key = object.getAnnotation(IsActivity.class).value();
String className = object.getSimpleName().toString();
String thisFiled = " public final static String " + className.toUpperCase() + "=\"" + key + "\";";
newFiled.add(thisFiled);
System.out.println("thisFiled:" + thisFiled);
}
for (String filed : oldFiled) {
if (filed.startsWith(" public final static String") && !newFiled.contains(filed)) {
newFiled.add(filed);
}
}
String[] mergeFiled = new String[newFiled.size()];
for (int i = 0; i < newFiled.size(); i++) {
mergeFiled[i] = newFiled.get(i) + "\n";
System.out.println("mergeFiled:" + mergeFiled[i]);
}
savePath.delete();
buildARouterConstantFile(savePath, mergeFiled);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {
int len = clazzElement.size();
String[] buffer = new String[len];
int i = 0;
for (Element object : clazzElement) {
String key = object.getAnnotation(IsActivity.class).value();
String className = object.getSimpleName().toString();
buffer[i] = " public final static String " + className.toUpperCase() + "=\"" + key + "\";\n";
System.out.println("buildARouterConstantFile:" + buffer[i]);
i++;
}
buildARouterConstantFile(savePath, buffer);
}
}
//构建常量文件
private void buildARouterConstantFile(File savePath, String... fileds) {
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(savePath);
FileChannel channel = fileOutputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024 * 100);
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("package com.lyl.arouter.constant;\n");
stringBuffer.append("\n");
stringBuffer.append("public class ARouterConstant\n");
stringBuffer.append("{\n");
for (String filed : fileds) {
stringBuffer.append(filed);
}
stringBuffer.append("\n}");
System.out.println(stringBuffer);
buffer.put(stringBuffer.toString().getBytes());
buffer.flip();
//将内容写到通道中
channel.write(buffer);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//将String转ByteBuffer
private ByteBuffer convertStringToByte(String content) throws UnsupportedEncodingException {
return ByteBuffer.wrap(content.getBytes("utf-8"));
}
//将ByteBuffer转String
public String decode(ByteBuffer bb) {
Charset charset = Charset.forName("utf-8");
return charset.decode(bb).toString();
}
运行将生成如下常量类
package com.lyl.arouter.constant;
public class ARouterConstant
{
public final static String MAINACTIVITY="com.lyl.practice/MainActivity";
public final static String LOGINACTIVITY="com.lyl.login/LoginActivity";
}
使用常量类
ARouter.getInstance().jumpActivity((Context) context, ARouterConstant.LOGINACTIVITY);
demo链接
链接: 《跨组件化路由实现——自动识别生成跳转字符串》.
吐槽
目前例子中生成常量相关代码是在arouter-compiler中,后续会抽离。