当前位置: 首页>后端>正文

Android仿butterKnife,练习APT技术(二)

接下来实操写一遍,这里只使用BindView一个注解,来学习其实现过程。

第一步

新建一个Java库,取名butterknife_annotations
目录结构如下,这里只有一个注解类BindView

Android仿butterKnife,练习APT技术(二),第1张
package com.example.butterknife_annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface BindView {
    int value();
}

第二步

再新建一个Java库,取名butterknife_complier,这个库用于生成MainActivity_ViewBinding
其目录如下:

Android仿butterKnife,练习APT技术(二),第2张

这个类就是用来查找支持的注解,并执行怎么生成代码的逻辑,不能调试代码,可以通过打印日志来查看指定位置的执行情况。这个是在编译期执行的,具体来说就是Javac来执行它,javac启动一个完整Java虚拟机来运行注解处理器,所以需要将这个类注册到Javac中。
有两种方式注册
  1. 需要在 butterknife_complier库的 main 目录下新建 resources 资源文件夹;
    在 resources文件夹下建立 META-INF/services 目录文件夹;
    在 META-INF/services 目录文件夹下创建 javax.annotation.processing.Processor 文件;
    在 javax.annotation.processing.Processor 文件写入注解处理器的全称,包括包路径;
    目录如图所示:


    Android仿butterKnife,练习APT技术(二),第3张

    在文件中写入注解处理器的全路径:

  2. 第一种手动添加的方式未免有些麻烦,并且容易出错,可以借助一个库自动生成
    在自定义注解处理器类的顶部加入注解:
    @AutoService(Processor.class),这个注解处理器是Google开发的,可以用来生成 META-INF/services/javax.annotation.processing.Processor 文件信息。
    如下图所示:


    Android仿butterKnife,练习APT技术(二),第4张

    编译之后会自动生成如第一种方式添加的文件,可以在butterknife_complier/build目录下查看生成结果:

Android仿butterKnife,练习APT技术(二),第5张

当然这里依赖要添加正确,不然可能会报错,依赖如下:

apply plugin: 'java-library'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

}

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

dependencies {
    implementation project(":butterknife_annotations") // 使用定义的注解
    implementation 'com.google.auto:auto-common:0.10' // 这个是auto-service基础库
    implementation 'com.squareup:javapoet:1.10.0' //这个用于生成Java代码
    compileOnly 'com.google.auto.service:auto-service:1.0-rc4' //提供@AutoService注解
    annotationProcessor 'com.google.auto.service:auto-service:1.0-rc4' // 用于生成注册服务文件
}

下一篇再分析生成MainActivity_ViewBinding的逻辑。

第三步

新建一个Android库,取名butterknife_runtime,是运行时使用,提供一个Butter Knife.bind(this);方法,完成绑定的属性初始化。
目录结构如下:

Android仿butterKnife,练习APT技术(二),第6张

Utils类时查找工具类,里面封装了findViewById。
好了,至此需要的三个库都创建完成了,下面使用一下,看能不能正常运行:
app模块下的build.gradle依赖如下:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    buildToolsVersion "28.0.3"

    defaultConfig {
        applicationId "com.example.ndk_2_3_2"
        minSdkVersion 28
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        externalNativeBuild {
            cmake {
                cppFlags ""
                abiFilters "x86" //本地库的cpu架构
            }
        }
        ndk {
            abiFilters "x86"  //指定第三方库的cup架构
         }

//        javaCompileOptions{
//            annotationProcessorOptions.includeCompileClasspath = true
//        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
    compileOptions{
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation project(':butterknife_annotations') //使用Bind View注解
    annotationProcessor project(':butterknife_complier') //生成Binding文件
    implementation project(":butterknife_runtime") // 提供 bind方法,完成属性初始化
//    implementation 'com.jakewharton:butterknife:10.2.3'
//    annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
}
Android仿butterKnife,练习APT技术(二),第7张

可以看到,生成了MainActivity_ViewBinding,跑到手机上看看:


Android仿butterKnife,练习APT技术(二),第8张

MainActivity代码如下:

package com.example.ndk_2_3_2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import com.example.butterknife_annotations.BindView;
import butterknife.ButterKnife;


public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @BindView(R.id.sample_text)
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        textView.setText(stringFromJNI()); //这里正确使用,说明绑定属性成功
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

好了,下一篇分析MainActivity_ViewBinding的生成过程。


https://www.xamrdz.com/backend/3gb1934678.html

相关文章: