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

网易那个自己做游戏的网站是什么原因百度seo排名点击器app

网易那个自己做游戏的网站是什么原因,百度seo排名点击器app,做网站用c 还是java,有什么网站是专门做电商详情页对于Android注解,或多或少都有一点接触,但相信大多数人都是在使用其它依赖库的时候接触的。因为有些库如果你想使用它就必须使用它所提供的注解。例如:ButterKnife、Dagger2、Room等等。 至于为何使用注解?使用过的应该都知道&…

clipboard.png

对于Android注解,或多或少都有一点接触,但相信大多数人都是在使用其它依赖库的时候接触的。因为有些库如果你想使用它就必须使用它所提供的注解。例如:ButterKnife、Dagger2、Room等等。

至于为何使用注解?使用过的应该都知道,最明显的就是方便、简洁。通过使用注解可以在项目编译阶段,帮助我们自动生成一些重复的代码,减轻我们的负担。典型的ButterKnife本质就是使用Android注解,通过注解来减少我们对view.findViewById的编写,提高我们的开发效率。上一个系列(AAC)的Room也是一样,我们可以简单的回顾一下:

@Entity(tableName = "contacts")
data class ContactsModel(@PrimaryKey@ColumnInfo(name = "contacts_id")val id: Int,@ColumnInfo(name = "name")val name: String,@ColumnInfo(name = "phone")val phone: String
)

通过使用注解来定义一个实体表,也就10行左右的代码。如果要我们全部自己写那绝对要两三百行代码了,而且其中还可能出错,又要改bug等等。效率就严重降低。对于依赖库如果都这么麻烦也就不会有人用了。

那么如何判断一个依赖库是否需要使用注解呢?其实很简单,只要记住以下两点即可:

  1. 需要生成的代码不能与项目逻辑有关
  2. Android注解只能生成代码,并不能修改代码
这里透露一下,Android注解的本质是使用Java的反射机制,后续会详细说明

项目架构

相信ButterKnife应该有接触过吧,没有的也没关系,现在正是时候。下面我们会自己实现BindView与OnClick注解,实现ButterKnife中的对应注解功能。那么我先来看下整体的项目架构

clipboard.png

通过项目图,我们可以清晰的看到,主要分为三个部分

  1. butterknife-annotations:注解库,包含BindView与OnClick等自定义的注解
  2. butterknife-bind:绑定库,自定义的注解与声明的类绑定
  3. butterknife-compiler: 解析编译生成库,解析声明类中的注解,在编译时自动生成相应的代码。

为了帮助大家能够更轻松的理解Android注解,今天主要分析的就是butterknife-annotations这个注解库。带大家一起来声明注解变量。

BindView

为了要实现开源库butterknife类似的绑定id效果,这里我们先定义一个BindView注解,具体如下:

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.FIELD)
public @interface BindView {@IdRes int[] value();
}

嗯,还是很简单的对吧。也就5行代码解决BindView注解的定义。

那么再来详细剖析这5行代码。

Retention

首先是第一行代码的Retention,看它的使用方式就能知道,它也是一个声明了的注解。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {/*** Returns the retention policy.* @return the retention policy*/RetentionPolicy value();
}

通过源码我们可以看出该注解只接收一个参数,该参数为RetentionPolicy类型。那么我们在进一步深入RetentionPolicy:

public enum RetentionPolicy {/*** Annotations are to be discarded by the compiler.*/SOURCE,/*** Annotations are to be recorded in the class file by the compiler* but need not be retained by the VM at run time.  This is the default* behavior.*/CLASS,/*** Annotations are to be recorded in the class file by the compiler and* retained by the VM at run time, so they may be read reflectively.** @see java.lang.reflect.AnnotatedElement*/RUNTIME
}

在这里我们发现它其实是一个枚举,在枚举中支持三个常量,分别为SOURCE、CLASS与RUNTIME。它们的区别主要是作用的周期范围,下面我再对这三个的作用进行翻译一遍:

  1. SOURCE: 使用该标明的注解将在编译阶段就被抛弃掉。
  2. CLASS:使用该标明的注解将在编译阶段记录到生成的class文件中,但在运行阶段时又会被VM抛弃。默认是该模式。
  3. RUNTIME:使用该标明的注解将在编译阶段被保存在生成的class文件中,同时在运行阶段时会保存到VM中。所以它该注解将一直存在,自然能够通过java的反射机制进行读取。

所以它们的存在的生命时长为SOURCE < CLASS < RUNTIME。知道了它的作用范围之后,我们在自定义注解时就要尽量较小注解的作用范围,提高项目的编译与运行速度。

因为我们的BindView注解只是为了进行Viwe的绑定,所以在编译之后就无需存在,所以这里就使用了CLASS来进行标明。

Target

下面我们在来看第二行代码,这里使用到了另一个注解Target,我们还是来看下它的源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {/*** Returns an array of the kinds of elements an annotation type* can be applied to.* @return an array of the kinds of elements an annotation type* can be applied to*/ElementType[] value();
}

可以看到注解的源码都非常简单,这里接收了一个ElementType数组参数,ElementType不难猜出它的类型也是一个枚举:

public enum ElementType {/** Class, interface (including annotation type), or enum declaration */TYPE,/** Field declaration (includes enum constants) */FIELD,/** Method declaration */METHOD,/** Formal parameter declaration */PARAMETER,/** Constructor declaration */CONSTRUCTOR,/** Local variable declaration */LOCAL_VARIABLE,/** Annotation type declaration */ANNOTATION_TYPE,/** Package declaration */PACKAGE,/*** Type parameter declaration** @since 1.8*/TYPE_PARAMETER,/*** Use of a type** @since 1.8*/TYPE_USE
}

ElementType中虽然有10常量,但我们实际真正常用的也就是前面8种。它们代表自定义的注解能够作用的对象。分别为:

  1. TYPE: 作用于类、接口或者枚举
  2. FIELD:作用于类中声明的字段或者枚举中的常量
  3. METHOD:作用于方法的声明语句中
  4. PARAMETER:作用于参数声明语句中
  5. CONSTRUCTOR:作用于构造函数的声明语句中
  6. LOCAL_VARIABLE:作用于局部变量的声明语句中
  7. ANNOTATION_TYPE:作用于注解的声明语句中
  8. PACKAGE:作用于包的声明语句中
  9. TYPE_PARAMETER:java 1.8之后,作用于类型声明的语句中
  10. TYPE_USE:java 1.8之后,作用于使用类型的任意语句中

结合我们的BindView的作用是对View进行id绑定,自然是作用与声明的字段上。所以在BindView中使用了FIELD。

再来看第四行代码

@IdRes int[] value()

有了上面的注解接触,不难理解这是标明BindView将接收一个int类型的数组参数。对于开源库butterknife中的BindView是接收需要绑定的View的id,这里我们做一个改版,再接收一个String的id,用来为绑定的View设置默认值。这样我们自定义了的BindView注释就完成了。

OnClick

下面我们再自定义一个OnClick点击的注解,经过上面的分析,可以在脑海中想想Retention与Target分别什么值?

想好了之后我们在来过一遍

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface OnClick {@IdRes int value();
}

Retention的作用范围与BindView一样首页SOURCE,在编译之后就无需存在;Target的作用对象与BindView不同,既然是点击事件的点击操作,自然是作用在操作逻辑的方法上,所以这里使用METHOD。

keep

文章开头有提及到本质是通过注解来自动生成代码,为我们创建所需的类,那么在实际开发中一旦我们的项目混淆了,这将会导致自动创建的类失效,从而导致我们自定义的注解失效。所以为了防止其失效,我们在这里再定义一个注解keep:

@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Keep {
}

Retention的作用范围是在class文件中还要能够被其它class调用,所以这里使用CLASS;Target作用对象是自动生成的类,所以使用TYPE。至于参数则不必要,它只是为了标明类,防止其被混淆。

总结

butterknife-annotations库中的自定义注解就完成了。通过上面的分析,我们注意点主要归结于以下三点:

  1. Retention: 明确注解作用的生命时长,尽早的消除
  2. Target: 明确注解作用的对象
  3. Keep: 防止后续自动生成的类被混淆

注解变量的定义就到这结束了,同时文章中的代码都可以在Github中获取到。使用时请将分支切换到feat_annotation_processing

如果感觉不错的话,可以点赞收藏哦,这是对我最大的支持,谢谢!

相关文章

自定义Android注解Part2:代码自动生成

自定义Android注解Part3:绑定

关注

私人博客

clipboard.png

http://www.lbrq.cn/news/2511541.html

相关文章:

  • h5响应式网站模板站内优化怎么做
  • 自己做网站费用潍坊网站排名提升
  • 学做网站需要哪几本书关键词竞价排名是什么意思
  • 招聘网站开发站长工具一区
  • 做鸡蛋期货看什么网站市场监督管理局官网入口
  • 开发中英文切换网站如何做网站关键词优化推广哪家快
  • 仲恺建设局网站搜索指数
  • 网站建设技术路线山西网页制作
  • 做一个招聘信息的网站 用什么做网站的软件网络推广外包业务怎么样
  • 电子商务的就业方向是什么天机seo
  • 3g版网站制作网站策划是什么
  • 免费网站怎么做排名电商运营培训大概多少学费
  • inititle 网站建设常用的网络推广的方法有哪些
  • delphi10.2 网站开发广告软文营销平台
  • 邮箱检测网站qq群推广网站免费
  • python整合网站开发技术今日nba战况
  • 公众号如何推广宣传百中搜优化软件
  • 重庆外贸网站建设公司百度官方营销推广平台加载中
  • 网上注册网站要钱吗沈阳今日新闻头条
  • 北京做网站男生工资百度开户怎么开
  • 网站制作网站深圳网站建设运营
  • 南阳做网站多少费用seo教程百度网盘
  • 个人网站设计及实现网站外包
  • 贵阳美容网站建设seo优化培训
  • 浦城 做网站西安百度推广网站建设
  • 网站关键词怎么做排名靠前下载百度到桌面
  • 机票网站开发知乎百度热搜榜排名今日
  • 网站导航条线上推广公司
  • 微信公众号怎么上架商品seo研究中心超逸seo
  • 苗木企业网站源码公司在百度怎么推广
  • 14、distance_object_model_3d算子
  • C++模板初阶
  • Vue、微信小程序、Uniapp 面试题整理最新整合版
  • C语言:函数
  • springboot基于Java的人力资源管理系统设计与实现
  • 【ee类保研面试】通信类---信息论