注解和序列化

[TOC]

lambda表达式

1.无参时,无返回值

1
Runnable runnabl = () -> System.out.println("adfa");

2.有一次参数

1
View.OnClickListener onClickListener = v -> System.out.println();

3.2个参数

1
2
MyCallback2 myCallback2 = (s, i) -> System.out.println("sfasdfa");
myCallback2.call("saf", 2);

函数 是第一等公民了

相当于函数指针 c/c++

1
2
3
4
5
6
7
8
9
10
11
view.setOnClickListener(v -> {
System.out.println();
});

//一行代码的时候,就这样写
view.setOnClickListener(v ->
System.out.println());


//带返回值的
Callable callable = () -> "11";

Method reference方法引用:

Inherited, Retotent默认是 source类型吗

@Repeatable 多个标签 jdk8 的新注解

反射必须是runtime,

可以让注解使用多次

运行时的注解,通过反射来进行获取

  1. 提供信息,编译器来进行检查错误。
  2. class类型的,通过注解信息来进行生成 代码和 html文档等
  3. 运行时的处理:某些注解可以程序运行时获取

annotationProcessor google内置的

apt,

processors注解扫描程序

@AutoService, auto-service

gradlew build

gradlew clear build

断点调试:

处理注解在 getsupportedAnnotationTypes中生成

build -> gen -> source -> apt

注解的使用场景,

source类型,编译器

class类型, apt

runtime类型, 在运行时去反射获取

aapt2 ,apk打包过程中就要用到一个工具,aapt2, 编译资源的

Wpa

攻克:annotationProcessor

annotationProcessor生成额外文件的规则是在依赖库里定义的,只在编译的时候执行,但是库最终不打包到apk中,所以使用Butterknife这类编译注解框架并不会增加apk的大小

使用:

  1. 先创建java libaray annotations, javaPoet ,processors ,创建androidlib api

接口利于扩展,本地定义好,Map<ViewFinder>, ViewFinder就代表了这一类,后面继承的ViewFinder,都可以在这个代码里面使用这个ViewFinder使用好的类

小插曲:

Android studio 默认jdk路径

/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home

mac本地安装的jdk路径 通过

/usr/libexec/java_home -V

进行查看, 内置的没有源码, 不是内置的路径的jdk有源码

插曲结束

  1. api写到一半写不下去了,需要生成的代码,然后引入javapoet项目,进行一顿修改,把jdk的版本调整到jdk 8,然后javapoet运行正常

  2. 然后进行编写Processors,需要导入

    1
    2
    3
    4
    5
    api project(':annotations')
    implementation 'com.google.auto.service:auto-service:1.0-rc4'
    implementation 'com.google.auto:auto-common:0.10'

    api project(':JavaPoet')
  3. javapoet的基本使用

    $T 会进行映射,自动import声明

    $S 代表一个string

    ClassName: 可以识别任何的声明类

    $N 可以应用另外一个通过名字生成的声明。

    Modifiers 创建接口和抽象类

    Constructors 可以用来创建构造函数

    Parameters 创建参数,或者使用类 MethodSpec 类中addParameters

    Fields

    创建枚举类型: typedec.enumBuilder()

    $L通过$L引用匿名内部类

  1. 默认返回值是void,所以methodSpec中的returns不是必须要写的

  2. 方法一定要有 addModifiers, 不然会报错

    modifiers [] must contain one of [abstract, static, default]

    如何跟大佬交流

  1. 遇到一个坑,就是在写完Processor的时候,没加resources这个,就不能生成apt文件,哎,弄了半小时,终于可以生成代码了,到时看看,不用这个可以生成代码没,先往下做

  2. 解决不能进行AutoService 不能进行启动Processor多个的问题; 编写好bindview

  3. gradlew clean build 通过这个命令进行看processor编译,然后打印

    1
    2
    3
    4
    ElementKind kind = element.getKind();
    TypeMirror typeMirror = element.asType();
    List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
    System.out.println("kind: " + kind + " typeMirror: " + typeMirror + " annotationMirrors:" + annotationMirrors);

    结果:

    kind: FIELD

    typeMirror: android.widget.TextView

    annotationMirrors: @com.sdxxtop.annotations.BindView(2131165325)

1
2
3
4
5
 variableElement.getSimpleName()
结果: mTextView
variableElement.getEnclosingElement()
结果:com.sdxxtop.annotationstudydemo.MainActivity
这玩意是关键啊
1
2
3
TypeName.get(hostElement.asType()).getClass() 不能 = hostElement.asType()

com.sdxxtop.javapoet.ClassName这个是ClassName

引用:

glide为什么可以同步生命周期

看懂编译注解annotationProcessor和kapt