当前位置: 首页 > news >正文

郑州虚拟货币网站开发建设家具网站

郑州虚拟货币网站开发,建设家具网站,用网站做宣传的费用,做平面有什么好的网站ButterKnife实现之Android注解处理器使用教程 1、新建一个注解 1.1、编译时注解 创建注解所需的元注解Retention包含3个不同的值#xff0c;RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME。这3个值代表注解不同的保留策略。 使用RetentionPolic…ButterKnife实现之Android注解处理器使用教程 1、新建一个注解 1.1、编译时注解 创建注解所需的元注解Retention包含3个不同的值RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME。这3个值代表注解不同的保留策略。 使用RetentionPolicy.RUNTIME的注解为运行时注解能在程序运行时通过反射获取注解的信息并进行逻辑处理使用RetentionPolicy.CLASS的注解为编译时注解能在程序编译时进行预处理操作比如生成一些辅助代码使用RetentionPolicy.SOURCE的注解能做一些检查性的操作比如Override和SuppressWarning。 1.2、新建注解 编译时注解能够帮助我们生成辅助代码能够满足在编译时获取注解信息生成带有findViewById的代码。所以我们新建一个编译时注解。新建注解前我们新建一个名为annotation的Java Library类型的Module。然后在这个Module新建这个注解命名为BindView代码如下 Retention(RetentionPolicy.CLASS) Target(ElementType.FIELD) public interface BindView {int value(); }2、新建注解处理器 注解处理器是处理注解的类处理编译时注解时我们需要编写一个注解处理器。注解处理器类需要继承AbstractProcessor类。本节我们来学习编写注解处理器跟上一节一样我们再次新建一个Java Libary的module这个module命名为processor并依赖包含注解的annotation Module在processor module的build.gradle添加如下代码 dependencies{implementation project(:annotation) }接着在这个module中我们新建一个注解处理器-MainProcessor它继承AbstractProcessor并实现AbstractProcess的4大方法我们来学习这4大方法。 2.1、AbstractProcessor的4大方法 /** * 注解处理器MainProcessor */ public class MainProcessor extends AbstractProcessor {Overridepublic synchronized void init(ProcessingEnvironment processingEnv) {super.init(processingEnv);}Overridepublic boolean process(Set? extends TypeElement annotations, RoundEnvironment roundEnv) {return false;}Overridepublic SetString getSupportedAnnotationTypes() {return super.getSupportedAnnotationTypes();}Overridepublic SourceVersion getSupportedSourceVersion() {return super.getSupportedSourceVersion();}继承AbstractProcessor需要重写上述代码段的4个方法依次介绍它们的作用 1、init方法被注解处理工具调用并输入ProcessingEnviroment参数。ProcessingEnviroment提供了很多有用的工具类比如Elements、Types、Filer和Messager等。 2、process方法相当于每个处理器的主函数main()在这里编写扫描、评估和处理注解的代码以及生成Java文件。输入参数RoundEnviroment可以让你查询包含特定注解的被注解元素。 3、getSupportedAnnotationTypes这是必须指定的方法指定这个注解处理器是注册给哪个注解的注意它的返回值是一个字符串的集合包含该处理器想要处理的注解类型的合法全称。 4、getSupportedSourceVersion用来指定你使用的Java版本通常这里返回SourceVersion.latestSupported()。 可以将MainProcessor的getSupportAnnotationTypes方法和getSupportedSourceVersion方法更新成如下 Overridepublic SetString getSupportedAnnotationTypes() {HashSetString typeSet new HashSet();typeSet.add(BindView.class.getCanonicalName());return typeSet;}Overridepublic SourceVersion getSupportedSourceVersion() {return SourceVersion.latestSupported();}2.2、JavaPoet的使用 前面说到过在程序编译时根据注解信息生成辅助文件JavaPoet是一个可以生成Java代码的第三方框架所以我们要利用它生成辅助文件。 1.添加JavaPoet依赖 implementation com.squareup:javapoet:1.7.02.JavaPoet Api使用 1、生成方法 以ButterKnife的bind方法为例初始化一个id为R.id.tv_hello的TextView代码如下 //这个MainActivity是个例子实际上使用的是注解所对应的Activity public void bind(MainActivity activity){activity.tvHello (TextView)(((android.app.Activity)activity).findViewById(R.id.tv_hello)); }使用JavaPoet生成这个方法 MethodSpec.Builder bindMethodBuilder MethodSpec.methodBuilder(bind) //方法名为bind.addModifiers(Modifier.PUBLIC) //方法修饰符Public.addParameter(MainActivity,activity)//方法的参数如MainActivity activity.returns(void.class); //返回值voidString code String.format(activity.%s(%s)(((android.app.Activity)activity).findViewById(%s));\n,tvHello,android.widget.TextView,R.id.tv_hello); bindMethodBuilder.addCode(code);2、生成类 以生成MainActivity的辅助类MainActivity_ViewBinding为例类的内容 public class MainActivity_ViewBinding{//bind方法就是上面生成的方法public void bind(MainActivity activity){tvTest (android.widget.TextView) ((android.app.Activity)activity).findViewById(R.id.tv_test);} }使用JavaPoet生成该类 TypeSpec.classBuilder(MainActivity_ViewBinding).addModifiers(Modifier.PUBLIC).addMethod(bindMethodBuilder.build()).build();这样的话完整的类就使用JavaPoet生成出来了。还有更多的JavaPoet的用法推荐看这篇文章基于JavaPoet自动生成java代码文件 2.3、编写process方法 接下来就是注解处理器的核心部分了我们通过process方法实现注解解析生成源码的功能。process方法中需要用到ProcessingEnviroment参数所以我们先处理init方法保存变量 public class MainProcessor extends AbstractProcessor {private Elements elementUtils;private ProcessingEnvironment processingEnvironment;Overridepublic synchronized void init(ProcessingEnvironment processingEnv) {super.init(processingEnv);elementUtils processingEnv.getElementUtils();processingEnvironment processingEnv;} }process方法的逻辑主要是解析注解和生成代码我就直接上代码了 Overridepublic boolean process(Set? extends TypeElement annotations, RoundEnvironment roundEnv) {/**生成的代码* 类MainActivity_ViewBinding,包名com.wei.annotation_processor_demo* 内容* public class MainActivity_ViewBinding{* public void bind(MainActivity activity){* tvTest (TextView) ((Activity)activity).findViewById(R.id.tv_test);* }* }*/Set? extends Element elementsAnnotatedWith roundEnv.getElementsAnnotatedWith(BindView.class);MapVariableElement, Integer elementMap new HashMap();for (Element element : elementsAnnotatedWith) {//获取被注解的字段VariableElement variableElement (VariableElement) element;//获取被注解的字段的类TypeElement enclosingElement (TypeElement) element.getEnclosingElement();String className enclosingElement.getSimpleName().toString();//获取注解BindView bindView variableElement.getAnnotation(BindView.class);int id bindView.value();//保存所有被注解的字段和注解的成员变量值用于生成代码elementMap.put(variableElement, id);//获取被注解的字段所在类的包名String packageName elementUtils.getPackageOf(enclosingElement).getQualifiedName().toString();//生成代码TypeSpec typeSpec generateCode(className, ClassName.bestGuess(enclosingElement.getQualifiedName().toString()), elementMap);//生成javaFileJavaFile javaFile JavaFile.builder(packageName, typeSpec).build();try {//生成java代码javaFile.writeTo(processingEnvironment.getFiler());} catch (IOException e) {e.printStackTrace();}}return true;}private TypeSpec generateCode(String className, ClassName parameterClass, MapVariableElement,Integer elementMap){//生成bind方法MethodSpec.Builder bindMethodBuilder MethodSpec.methodBuilder(bind).addModifiers(Modifier.PUBLIC).addParameter(parameterClass,activity).returns(void.class);for (Map.EntryVariableElement, Integer entry : elementMap.entrySet()) {String fieldName entry.getKey().getSimpleName().toString();String fieldType entry.getKey().asType().toString();String code String.format(activity.%s(%s)(((android.app.Activity)activity).findViewById(%s));\n,fieldName,fieldType,String.valueOf(entry.getValue()));processingEnvironment.getMessager().printMessage(Diagnostic.Kind.NOTE,fieldName:fieldName,fieldType:fieldType,code:code);bindMethodBuilder.addCode(code);}return TypeSpec.classBuilder(className_ViewBinding).addModifiers(Modifier.PUBLIC).addMethod(bindMethodBuilder.build()).build();}2.4、注册注解处理器 为了能使用注解处理器需要用一个服务文件来注册它。文件路径为processor module的根目录/resources/META-INF.services/javax.annotation.processing.Processor。在javax.annotation.processing.Processor中添加内容com.wei.processor.MainProcessor。这样就成功注册了注解处理器同时需要注意2点1.文件路径中的文件夹可能不存在需要手动创建2.文件内容是注解处理器的包名类名不要照抄我的。 AutoService 如果不想手动添加服务文件就使用AutoService框架来生成服务文件。 使用步骤 1、添加依赖 //google autoService implementation com.google.auto.service:auto-service:1.0-rc4 annotationProcessor com.google.auto.service:auto-service:1.0-rc42、使用 在注解处理器的类上添加AutoService注解即可 AutoService(Processor.class) public class MainProcessor extends AbstractProcessor { //省略内容 //... }这样就实现了刚才我们手动创建服务文件同样的功能。 3、使用 注解处理器编写结束了我们需要验证是否能够实现ButterKnife同样的效果。验证方法我们在app module中添加annotation、processor两个库的依赖在MainActivity中使用BindView注解看看app module根目录/build/ap_generated_sources/debug/out/有无MainActivity_ViewBinding文件生成。 添加依赖 implementation project(:annotation) // implementation project(:processor)annotationProcessor project(:processor)使用annotationProcessor代替implementation有以下好处 1、annotationProcessor引用的库只会在编译期间被依赖使用不会打包进入apk因为注册处理器是在编译期间使用的打包进入apk会占用空间 2、为注解处理器生成的代码设置好路径以便Android Studio能找到它 使用BindView注解 public class MainActivity extends AppCompatActivity {BindView(R.id.tv_hello)TextView tvHello;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}查看生成文件 使用 生成ViewBinding类后可以通过反射执行该类bind方法实现findViewById逻辑 private void bind() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {Class? clazz Class.forName(getClass().getName() _ViewBinding);System.out.println(getClass().getName());Method bind clazz.getDeclaredMethod(bind, getClass());bind.invoke(clazz.newInstance(), this); }调用这个方法也就实现了findViewById逻辑最后 BindView(R.id.tv_hello) TextView tvHello;Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);try {bind();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}tvHello.setText(我成功了); }4、参考文章 感谢一下文章提供的教程万分感激 1、Android APT技术学习 2、基于JavaPoet自动生成java代码文件 3、深入理解编译注解二annotationProcessor与android-apt
http://www.w-s-a.com/news/578824/

相关文章:

  • 网站有情链接怎么做住房公积金个体工商户
  • 内蒙古网站开发网站开发验收资料
  • 温州网站建设首选国鼎网络网络营销方法可分为两类
  • 做张家界旅游网站多少钱企业推广网络营销
  • 代做毕设网站推荐广东手机微信网站制作
  • 福州建设工程质量监督网站专业做公司宣传网站的
  • 百度云建站教程网站工程师是做什么的
  • 手机在线制作网站一级消防工程师考试试题及答案
  • 网站设计的需求网页制作教程和素材
  • 徐州网站建设 网站推广WordPress 文章编辑
  • 做什么网站比较受欢迎软件商店下载安装2023版本最新
  • 做ip资讯的网站怎么在wordpress中套用同行网页
  • 医院网站如何备案东莞优化公司收费
  • 罗村网站开发适合ps做图的素材网站有哪些
  • 网站建设中 油财宝企业网址怎么整
  • asp.net空网站php网站开发要学什么
  • 做可视化的网站微信网站模版下载
  • 包头移动的网站建设茂名建站价格
  • 网站文章内容一键排版功能铜山网站建设
  • cdr可不可做网站对网站建设起到计划和指导的作用
  • 合肥最好的网站建设网页设计心得体会2000字
  • 西安网站品牌建设门户网站类型
  • 网上做调查问卷的网站请人做网站域名和主机
  • 个人网站模板html5找公司网站建设
  • 找最新游戏做视频网站一个做网站的团队需要哪些人员
  • 威海市做网站的做网站很难吗
  • 广州房地产网站建设方案怎么免费申请网站
  • 免费生成网站软件下载影视公司名字取名
  • 网站公司提供程序免费的网页入口
  • jsp网站开发实例教学房产网站怎么做400电话