没有合适的资源?快使用搜索试试~ 我知道了~
【Android】Jetpack全组件实战开发短视频应用App(四)
6 下载量 76 浏览量
2021-01-03
16:26:59
上传
评论 1
收藏 307KB PDF 举报
温馨提示
前言 我们在上一篇基本上已经实现我们要的效果了,但是还遗留了几个问题,这一篇我们就来解决下 自定义解析器 我们上一篇介绍过NavDestination是通过解析xml生成的,我们不想在xml中写死,通过注解的方式实现,我们接下来就自定义注解和解析器来实现 创建 首先创建两个module annotation模块的gradle apply plugin: 'java-library' tasks.withType(JavaCompile) { options.encoding = UTF-8 } dependencies { implementation fileTree(
资源推荐
资源详情
资源评论
【【Android】】Jetpack全组件实战开发短视频应用全组件实战开发短视频应用App(四四)
前言前言
我们在上一篇基本上已经实现我们要的效果了,但是还遗留了几个问题,这一篇我们就来解决下
自定义解析器自定义解析器
我们上一篇介绍过NavDestination是通过解析xml生成的,我们不想在xml中写死,通过注解的方式实现,我们接下来就自定义注解和解析器来实现
创建创建
首先创建两个module
annotation模块的gradle
apply plugin: 'java-library'
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
sourceCompatibility = "8"
targetCompatibility = "8 "
compiler模块的gradle
apply plugin: 'java-library'
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':libnavannotation')
//生成json
implementation 'com.alibaba:fastjson:1.2.59'
//这俩必须
implementation 'com.google.auto.service:auto-service:1.0-rc6'
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6'
}
sourceCompatibility = "8"
targetCompatibility = "8"
编写注解编写注解
我们既想让Fragment使用,也让Activity使用,所以我们创建连个类FragmentDestination和ActivityDestination,我们还要添加几个属性pageUrl,needLogin,asStarter。pageUrl是为了给NavController跳转
的时候使用的,asStarter表示是不是第一个页,needLogin这个为了以后要用,点击的时候我们判断是否需要加权限
@Target(ElementType.TYPE)
public @interface ActivityDestination {
String pageUrl();
boolean needLogin() default false;
boolean asStarter() default false;
}
@Target(ElementType.TYPE)
public @interface FragmentDestination {
String pageUrl();
boolean needLogin() default false;
boolean asStarter() default false;
}
编写解析器编写解析器
/**
* APP页面导航信息收集注解处理器
*
* AutoService注解:就这么一标记,annotationProcessor project()应用一下,编译时就能自动执行该类了。
*
* SupportedSourceVersion注解:声明我们所支持的jdk版本
*
* SupportedAnnotationTypes:声明该注解处理器想要处理那些注解
*/
@AutoService(Processor.class)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes({"com.hfs.libnavannotation.FragmentDestination", "com.hfs.libnavannotation.ActivityDestination"})
public class NavProcessor extends AbstractProcessor {
@Override
public boolean process(Set set, RoundEnvironment roundEnvironment) {
return false;
}
}
这里我们还需要两个类,一个是Messager,另一个是Filer
Messager :打印日志
Filer: 文件操作相关,我们想把生成的json文件存放在某个文件夹下面
初始化这两个类
private Messager mMessager;
private Filer mFiler;
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
processingEnvironment.getMessager();
//日志打印,在java环境下不能使用android.util.log.e()
mMessager = processingEnv.getMessager();
//文件处理工具
mFiler = processingEnv.getFiler();
}
接下来就是process这个方法了
@Override
public boolean process(Set set, RoundEnvironment roundEnvironment) {
//通过处理器环境上下文roundEnv分别获取 项目中标记的FragmentDestination.class 和ActivityDestination.class注解。
//此目的就是为了收集项目中哪些类 被注解标记了
Set fragmentElements = roundEnvironment.getElementsAnnotatedWith(FragmentDestination.class);
Set activityElements = roundEnvironment.getElementsAnnotatedWith(ActivityDestination.class);
if (!fragmentElements.isEmpty() ||! activityElements.isEmpty()) {
HashMap destMap = new HashMap();
//分别 处理FragmentDestination 和 ActivityDestination 注解类型
//并收集到destMap 这个map中。以此就能记录下所有的页面信息了
handleDestination(fragmentElements, FragmentDestination.class, destMap);
handleDestination(activityElements, ActivityDestination.class, destMap);
//app/src/main/assets
FileOutputStream fos = null;
OutputStreamWriter writer = null;
try {
//filer.createResource()意思是创建源文件
//我们可以指定为class文件输出的地方,
//StandardLocation.CLASS_OUTPUT:java文件生成class文件的位置,/app/build/intermediates/javac/debug/classes/目录下
//StandardLocation.SOURCE_OUTPUT:java文件的位置,一般在/ppjoke/app/build/generated/source/apt/目录下
//StandardLocation.CLASS_PATH 和 StandardLocation.SOURCE_PATH用的不多,指的了这个参数,就要指定生成文件的pkg包名了
FileObject resource = mFiler.createResource(StandardLocation.CLASS_OUTPUT, "", OUTPUT_FILE_NAME);
String resourcePath = resource.toUri().getPath();
mMessager.printMessage(Diagnostic.Kind.NOTE, "resourcePath:" + resourcePath);
//由于我们想要把json文件生成在app/src/main/assets/目录下,所以这里可以对字符串做一个截取,
//以此便能准确获取项目在每个电脑上的 /app/src/main/assets/的路径
String appPath = resourcePath.substring(0, resourcePath.indexOf("app") + 4);
String assetsPath = appPath + "src/main/assets/";
File file = new File(assetsPath);
if (!file.exists()) {
file.mkdirs();
}
//此处就是稳健的写入了
File outPutFile = new File(file, OUTPUT_FILE_NAME);
if (outPutFile.exists()) {
outPutFile.delete();
}
outPutFile.createNewFile();
//利用fastjson把收集到的所有的页面信息 转换成JSON格式的。并输出到文件中
String content = JSON.toJSONString(destMap);
fos = new FileOutputStream(outPutFile);
writer = new OutputStreamWriter(fos, "UTF-8");
writer.write(content);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return true;
}
真正逻辑都在handleDestination中,我们下面再说这个,我们先看上面那些代码,比较好理解,我们拿到被注解标记的类的结合后,交给handleDestination处理,下面是把文件写
在app/src/main/assets目录中,接下来我们就来看下handleDestination方法
private void handleDestination(Set elements, Class annotationClaz, HashMap destMap) {
for (Element element : elements) {
//TypeElement是Element的一种。
//如果我们的注解标记在了类名上。所以可以直接强转一下。使用它得到全类名
TypeElement typeElement = (TypeElement) element;
//全类名com.hfs.jokevideo.home
剩余6页未读,继续阅读
资源评论
weixin_38716563
- 粉丝: 5
- 资源: 871
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功