完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>
標(biāo)簽 > Processor
Processor的中文意思是:處理器,Intel Processor即Intel 系列處理器。是一塊超大規(guī)模的集成電路,是一臺計算機的運算核心(Core)和控制核心( Control Unit)。
Processor的中文意思是:處理器,Intel Processor即Intel 系列處理器。
中央處理器(CPU,Central Processing Unit)是一塊超大規(guī)模的集成電路,是一臺計算機的運算核心(Core)和控制核心( Control Unit)。
主要分為兩大類型:
Intel系列處理器和AMD系列處理器。
Processor的中文意思是:處理器,Intel Processor即Intel 系列處理器。
中央處理器(CPU,Central Processing Unit)是一塊超大規(guī)模的集成電路,是一臺計算機的運算核心(Core)和控制核心( Control Unit)。
主要分為兩大類型:
Intel系列處理器和AMD系列處理器。
一小時搞明白注解處理器(Annotation Processor Tool)
Java中的注解是個很神奇的東西,還不了解的可以看下一小時搞明白自定義注解(Annotation)。現(xiàn)在很多Android的庫都用使用注解實現(xiàn)的,比如ButterKnife,我們不防也來學(xué)習(xí)一下,學(xué)完注解處理器,我們嘗試寫一個簡單的類似ButterKnife的東西來綁定控件。
什么是注解處理器?
注解處理器是(Annotation Processor)是javac的一個工具,用來在編譯時掃描和編譯和處理注解(Annotation)。你可以自己定義注解和注解處理器去搞一些事情。一個注解處理器它以Java代碼或者(編譯過的字節(jié)碼)作為輸入,生成文件(通常是java文件)。這些生成的java文件不能修改,并且會同其手動編寫的java代碼一樣會被javac編譯。看到這里加上之前理解,應(yīng)該明白大概的過程了,就是把標(biāo)記了注解的類,變量等作為輸入內(nèi)容,經(jīng)過注解處理器處理,生成想要生成的java代碼。
處理器AbstractProcessor
處理器的寫法有固定的套路,繼承AbstractProcessor。如下:
public class MyProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
}
@Override
public Set《String》 getSupportedAnnotationTypes() {
return null;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set《? extends TypeElement》 annotations, RoundEnvironment roundEnv) {
return true;
}
}
init(ProcessingEnvironment processingEnv) 被注解處理工具調(diào)用,參數(shù)ProcessingEnvironment 提供了Element,F(xiàn)iler,Messager等工具
getSupportedAnnotationTypes() 指定注解處理器是注冊給那一個注解的,它是一個字符串的集合,意味著可以支持多個類型的注解,并且字符串是合法全名。
getSupportedSourceVersion 指定Java版本
process(Set《? extends TypeElement》 annotations, RoundEnvironment roundEnv) 這個也是最主要的,在這里掃描和處理你的注解并生成Java代碼,信息都在參數(shù)RoundEnvironment 里了,后面會介紹。
在Java7 中還可以使用
@SupportedSourceVersion(SourceVersion.latestSupported())
@SupportedAnnotationTypes({
// 合法注解全名的集合
})
代替 getSupportedSourceVersion() 和 getSupportedAnnotationType() ,沒毛病,還可以在注解處理離器中使用注解。
注冊注解處理器
打包注解處理器的時候需要一個特殊的文件 javax.annotation.processing.Processor 在 META-INF/services 路徑下
--myprcessor.jar
----com
------example
--------MyProcessor.class
----META-INF
------services
--------javax.annotation.processing.Processor
打包進javax.annotation.processing.Processor的內(nèi)容是處理器的合法全稱,多個處理器之間換行。
com.example.myprocess.MyProcessorA
com.example.myprocess.MyProcessorB
google提供了一個注冊處理器的庫
compile ‘com.google.auto.service:auto-service:1.0-rc2’
一個注解搞定:
@AutoService(Processor.class)
public class MyProcessor extends AbstractProcessor {
。。.
}
讀到這里ButterKnife用到的知識點我們都已經(jīng)了解了
1.自定義注解
2.用注解處理器解析注解
3.解析完成后生成Java文件
BufferKnife使用:
public class MainActivity extends AppCompatActivity {
@Bind(R.id.rxjava_demo)
Button mRxJavaDemo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mRxJavaDemo.setText(“Text”);
}
}
然后我們編譯一下,打開路徑:/app/build/intermediates/classes/release/com/ming/rxdemo/MainActivity$$ViewBinder.class
這就是我們生成的Java文件,可以看到Button已經(jīng)在bind里面初始化了。
public class MainActivity$$ViewBinder《T extends MainActivity》 implements ViewBinder《T》 {
public MainActivity$$ViewBinder() {
}
public void bind(Finder finder, T target, Object source) {
View view = (View)finder.findRequiredView(source, 2131492944, “field \‘mRxJavaDemo\’”);
target.mRxJavaDemo = (Button)finder.castView(view, 2131492944, “field \‘mRxJavaDemo\’”);
}
public void unbind(T target) {
target.mRxJavaDemo = null;
}
}
接下來我們創(chuàng)建一個項目,寫一個簡單的用注解綁定控件的例子
項目結(jié)構(gòu)
--apt-demo
----bindview-annotation(Java Library)
----bindview-api(Android Library)
----bindview-compiler(Java Library)
----app(Android App)
bindview-annotation 注解聲明
bindview-api 調(diào)用Android SDK API
bindview-compiler 注解處理器相關(guān)
app 測試App
1.在 bindview-annotation 下創(chuàng)建一個@BindView注解,該注解返回一個值,整型,名字為value,用來表示控件ID。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface BindView {
/**
* 用來裝id
*
* @return
*/
int value();
}
2.在 bindview-compiler 中創(chuàng)建注解處理器 BindViewProcessor 并注冊,做基本的初始化工作。
@AutoService(Processor.class)
public class BindViewProcessor extends AbstractProcessor {
/**
* 文件相關(guān)的輔助類
*/
private Filer mFiler;
/**
* 元素相關(guān)的輔助類
*/
private Elements mElementUtils;
/**
* 日志相關(guān)的輔助類
*/
private Messager mMessager;
/**
* 解析的目標(biāo)注解集合
*/
private Map《String, AnnotatedClass》 mAnnotatedClassMap = new HashMap《》();
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
mElementUtils = processingEnv.getElementUtils();
mMessager = processingEnv.getMessager();
mFiler = processingEnv.getFiler();
}
@Override
public Set《String》 getSupportedAnnotationTypes() {
Set《String》 types = new LinkedHashSet《》();
types.add(BindView.class.getCanonicalName());//返回該注解處理器支持的注解集合
return types;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
public boolean process(Set《? extends TypeElement》 annotations, RoundEnvironment roundEnv) {
return true;
}
}
是不是注意到了里面有個Map容器,而且類型是AnnotatedClass,這是干啥的呢?這個很好理解,我們在解析XML,解析Json的時候數(shù)據(jù)解析完之后是不是要以對象的形式表示出來,這里也一樣,@BindView用來標(biāo)記類成員,一個類下可以有多個成員,好比一個Activity中可以有多個控件,一個容器下有多個控件等。如下:
package com.mingwei.myprocess.model;
import com.mingwei.myprocess.TypeUtil;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
/**
* Created by mingwei on 12/10/16.
* CSDN: http://blog.csdn.net/u013045971
* Github: https://github.com/gumingwei
*/
public class AnnotatedClass {
/**
* 類名
*/
public TypeElement mClassElement;
/**
* 成員變量集合
*/
public List《BindViewField》 mFiled;
/**
* 元素輔助類
*/
public Elements mElementUtils;
public AnnotatedClass(TypeElement classElement, Elements elementUtils) {
this.mClassElement = classElement;
this.mElementUtils = elementUtils;
this.mFiled = new ArrayList《》();
}
/**
* 獲取當(dāng)前這個類的全名
*/
public String getFullClassName() {
return mClassElement.getQualifiedName().toString();
}
/**
* 添加一個成員
*/
public void addField(BindViewField field) {
mFiled.add(field);
}
/**
* 輸出Java
*/
public JavaFile generateFinder() {
return null;
}
/**
* 包名
*/
public String getPackageName(TypeElement type) {
return mElementUtils.getPackageOf(type).getQualifiedName().toString();
}
/**
* 類名
*/
private static String getClassName(TypeElement type, String packageName) {
int packageLen = packageName.length() + 1;
return type.getQualifiedName().toString().substring(packageLen).replace(‘。’, ‘$’);
}
}
成員用BindViewField表示,沒什么復(fù)雜的邏輯,在構(gòu)造函數(shù)判斷類型和初始化,簡單的get函數(shù)
package com.mingwei.myprocess.model;
import com.mingwe.myanno.BindView;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
/**
* Created by mingwei on 12/10/16.
* CSDN: http://blog.csdn.net/u013045971
* Github: https://github.com/gumingwei
* 被BindView注解標(biāo)記的字段的模型類
*/
public class BindViewField {
private VariableElement mFieldElement;
private int mResId;
public BindViewField(Element element) throws IllegalArgumentException {
if (element.getKind() != ElementKind.FIELD) {//判斷是否是類成員
throw new IllegalArgumentException(String.format(“Only field can be annotated with @%s”,
BindView.class.getSimpleName()));
}
mFieldElement = (VariableElement) element;
//獲取注解和值
BindView bindView = mFieldElement.getAnnotation(BindView.class);
mResId = bindView.value();
if (mResId 《 0) {
throw new IllegalArgumentException(String.format(“value() in %s for field % is not valid”,
BindView.class.getSimpleName(), mFieldElement.getSimpleName()));
}
}
public Name getFieldName() {
return mFieldElement.getSimpleName();
}
public int getResId() {
return mResId;
}
public TypeMirror getFieldType() {
return mFieldElement.asType();
}
}
這里看到了很多的Element,在Xml解析時候就有Element這個概念。在Java源文件中同樣有Element概念:
package com.example; // PackageElement
public class MyClass { // TypeElement
private int a; // VariableElement
private Foo other; // VariableElement
public Foo () {} // ExecuteableElement
public void setA ( // ExecuteableElement
int newA // TypeElement
) {
}
}
接下來就是在處理器的process中解析注解了
每次解析前都要清空,因為process方法可能不止走一次。
拿到注解模型之后遍歷調(diào)用生成Java代碼
@Override
public boolean process(Set《? extends TypeElement》 annotations, RoundEnvironment roundEnv) {
mAnnotatedClassMap.clear();
try {
processBindView(roundEnv);
} catch (IllegalArgumentException e) {
error(e.getMessage());
return true;
}
try {
for (AnnotatedClass annotatedClass : mAnnotatedClassMap.values()) {
info(“generating file for %s”, annotatedClass.getFullClassName());
annotatedClass.generateFinder().writeTo(mFiler);
}
} catch (Exception e) {
e.printStackTrace();
error(“Generate file failed,reason:%s”, e.getMessage());
}
return true;
}
processBindView 和 getAnnotatedClass
/**
* 遍歷目標(biāo)RoundEnviroment
* @param roundEnv
*/
private void processBindView(RoundEnvironment roundEnv) {
for (Element element : roundEnv.getElementsAnnotatedWith(BindView.class)) {
AnnotatedClass annotatedClass = getAnnotatedClass(element);
BindViewField field = new BindViewField(element);
annotatedClass.addField(field);
}
}
/**
* 如果在map中存在就直接用,不存在就new出來放在map里
* @param element
*/
private AnnotatedClass getAnnotatedClass(Element element) {
TypeElement encloseElement = (TypeElement) element.getEnclosingElement();
String fullClassName = encloseElement.getQualifiedName().toString();
AnnotatedClass annotatedClass = mAnnotatedClassMap.get(fullClassName);
if (annotatedClass == null) {
annotatedClass = new AnnotatedClass(encloseElement, mElementUtils);
mAnnotatedClassMap.put(fullClassName, annotatedClass);
}
return annotatedClass;
}
3.在生成Java之前 我們要在bindview-api 中創(chuàng)建一些類,配合 bindview-compiler 一起使用。
你在使用Butterknife的時候不是要在onCreate里掉用一下BindView.bind(this)嗎,那這個玩意是干什么呢。試想一下,前面做的一大堆工作是為了生成自動綁定控件的Java代碼,如果生成的Java代碼不能和你要使用的地方關(guān)聯(lián)起來,那也是沒有用的,可以把BindView.bind(this)理解為調(diào)用了你生成的Java代碼,而生成了代碼中完成了一些控件的初始化工作,自然你的控件就變得可用了。
接口:Finder 定義findView方法
實現(xiàn)類:ActivityFinder Activity中使用,ViewFinder View中使用
接口:Injector inject方法將來是要創(chuàng)建在生成的Java文件中,用該方法中傳遞過來的參數(shù)進行控件的初始化。
輔助類:ViewInjector 調(diào)用和傳遞參數(shù)
這個代碼我就不貼了,就一點點內(nèi)容,一看就明白了。
4.在AnnotatedClass中生成Java代碼
生成代碼使用了一個很好用的庫 Javapoet 。類,方法,都可以使用構(gòu)建器構(gòu)建出來,很好上手,再也不用拼接字符串了。哈哈哈哈~
public JavaFile generateFinder() {
//構(gòu)建方法
MethodSpec.Builder injectMethodBuilder = MethodSpec.methodBuilder(“inject”)
.addModifiers(Modifier.PUBLIC)//添加描述
.addAnnotation(Override.class)//添加注解
.addParameter(TypeName.get(mClassElement.asType()), “host”, Modifier.FINAL)//添加參數(shù)
.addParameter(TypeName.OBJECT, “source”)//添加參數(shù)
.addParameter(TypeUtil.FINDER, “finder”);//添加參數(shù)
for (BindViewField field : mFiled) {
//添加一行
injectMethodBuilder.addStatement(“host.$N=($T)finder.findView(source,$L)”, field.getFieldName()
, ClassName.get(field.getFieldType()), field.getResId());
}
String packageName = getPackageName(mClassElement);
String className = getClassName(mClassElement, packageName);
ClassName bindClassName = ClassName.get(packageName, className);
//構(gòu)建類
TypeSpec finderClass = TypeSpec.classBuilder(bindClassName.simpleName() + “$$Injector”)//類名
.addModifiers(Modifier.PUBLIC)//添加描述
.addSuperinterface(ParameterizedTypeName.get(TypeUtil.INJECTOR, TypeName.get(mClassElement.asType())))//添加接口(類/接口,范型)
.addMethod(injectMethodBuilder.build())//添加方法
.build();
return JavaFile.builder(packageName, finderClass).build();
}
public String getPackageName(TypeElement type) {
return mElementUtils.getPackageOf(type).getQualifiedName().toString();
}
private static String getClassName(TypeElement type, String packageName) {
int packageLen = packageName.length() + 1;
return type.getQualifiedName().toString().substring(packageLen).replace(‘。’, ‘$’);
}
可以在代碼里System.out調(diào)試注解處理器的代碼。
還要注意的一點,項目之間的相互引用。
bindview-complier 引用 bindview-annotation
app 引用了剩下的三個module,在引用 bindview-complier 的時候用的apt的方式
apt project(‘:bindview-compiler’)
就寫到這里吧,Demo 放在 Github上了
2
0
標(biāo)簽:Processor 3033 2
2
0
DSP中這個問題怎么解決 [E0002] Invalid instruction for specified processor version?
標(biāo)簽:Processor 13178 2
GC5330,pdf _5330 Wideband Digital Tx and Rx Processor立即下載
類別:IC datasheet pdf 2011-06-13 標(biāo)簽:ProcessorWidebandGC5330
TPS3828-50-Q1,pdf(Processor Su立即下載
類別:IC datasheet pdf 2010-10-25 標(biāo)簽:Processor
TPS3828-50,pdf(Processor Super立即下載
類別:IC datasheet pdf 2010-10-25 標(biāo)簽:Processor
TPS3828-33-Q1,pdf(Processor Su立即下載
類別:IC datasheet pdf 2010-10-25 標(biāo)簽:Processor
TPS3828-33,pdf(Processor Super立即下載
類別:IC datasheet pdf 2010-10-25 標(biāo)簽:Processor
TPS3825-50-Q1,pdf(Processor Su立即下載
類別:IC datasheet pdf 2010-10-25 標(biāo)簽:Processor
TPS3825-50,pdf(Processor Super立即下載
類別:IC datasheet pdf 2010-10-25 標(biāo)簽:Processor
Simple Circuit Activates Fan W
Abstract: A circuit is shown that senses the temperature of a remote thermal...
2009-04-18 標(biāo)簽:Processor 1122 0
編輯推薦廠商產(chǎn)品技術(shù)軟件/工具OS/語言教程專題
電機控制 | DSP | 氮化鎵 | 功率放大器 | ChatGPT | 自動駕駛 | TI | 瑞薩電子 |
BLDC | PLC | 碳化硅 | 二極管 | OpenAI | 元宇宙 | 安森美 | ADI |
無刷電機 | FOC | IGBT | 逆變器 | 文心一言 | 5G | 英飛凌 | 羅姆 |
直流電機 | PID | MOSFET | 傳感器 | 人工智能 | 物聯(lián)網(wǎng) | NXP | 賽靈思 |
步進電機 | SPWM | 充電樁 | IPM | 機器視覺 | 無人機 | 三菱電機 | ST |
伺服電機 | SVPWM | 光伏發(fā)電 | UPS | AR | 智能電網(wǎng) | 國民技術(shù) | Microchip |
Arduino | BeagleBone | 樹莓派 | STM32 | MSP430 | EFM32 | ARM mbed | EDA |
示波器 | LPC | imx8 | PSoC | Altium Designer | Allegro | Mentor | Pads |
OrCAD | Cadence | AutoCAD | 華秋DFM | Keil | MATLAB | MPLAB | Quartus |
C++ | Java | Python | JavaScript | node.js | RISC-V | verilog | Tensorflow |
Android | iOS | linux | RTOS | FreeRTOS | LiteOS | RT-THread | uCOS |
DuerOS | Brillo | Windows11 | HarmonyOS |