版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39923324/article/details/82147299
无意间都到一篇《走心的安卓工程师跳槽经验分享》,发现自己工作几年了,技术方面虽然有了飞跃的进步,可是不知道自己的技术到了什么地步,每个方面我都涉及到了,但都不深,这大概是初级工程师的诟病吧!
即使知道也不知道从何下手,非常感谢《走心的安卓工程师跳槽经验分享》的作者!
感兴趣的朋友和我一起走下去吧!
04注解
什么是注解以及运行时注解的使用。(上)
使用编译时注解简单实现类似 ButterKnife 的效果(下)
定义:
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。(引用)
使用编译时注解简单实现类似 ButterKnife 的效果(下)
package com.yancy.mybutterknife;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 创建日期:2018/8/28 0028 on 11:42
* 描述:findViewById
* 作者: yancy
*/
//注解保留在源码中不且编译时被编译器保留,而且运行时也不会被JVM忽略,
@Retention(RetentionPolicy.RUNTIME)
//域或者属性 :ElementType.FIELD
@Target(ElementType.FIELD)
public @interface BindView {
//接受int类型的值 id
int value();
}
package com.yancy.mybutterknife;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 创建日期:2018/8/28 0028 on 11:50
* 描述:控件点击事件
* 作者: yancy
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
int[] value();
}
package com.yancy.mybutterknife;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* 创建日期:2018/8/28 0028 on 11:53
* 描述: 黄油刀
* 作者: yancy
*/
public class ButterKnife {
private static final String TAG = "yancy";
public static void bind(Activity activity){
Class<? extends Activity> clazz = activity.getClass();
Field[] fields = clazz.getFields();
//打印是否是我想要的属性
Log.e(TAG, "bind: fields=" + Arrays.toString(fields));
//编写findViewById核心代码
injectView(activity, fields);
Method[] methods = clazz.getMethods();
//打印是否是我想要的方法
Log.e(TAG, "bind: methods=" + Arrays.toString(methods));
//编写OnClick事件
injectOnclick(activity, methods);
}
public static void unBind(){
}
private static void injectOnclick(final Activity activity, Method[] methods) {
for (final Method method : methods) {
OnClick onClick = method.getAnnotation(OnClick.class);
if (onClick != null) {
int ids[] = onClick.value();
for (int id : ids) {
if (id != -1) {
View view = activity.findViewById(id);
if (view != null) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
method.invoke(activity, v);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
});
}
}
}
}
}
}
private static void injectView(Activity activity, Field[] fields) {
for (Field field : fields) {
BindView bindView = field.getAnnotation(BindView.class);
if (bindView != null) {
int id = bindView.value();
if (id != -1) {
View view = activity.findViewById(id);
try {
field.set(activity, view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}
package com.yancy.mybutterknife;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@BindView(R.id.tv)
TextView mTV;
@BindView(R.id.btn)
Button mBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick(R.id.btn)
public void onClick(View view){
mTV.setText("注解测试ok");
}
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unBind();
}
}
以上大码简单的实现了ButterKnife 的效果,但是这种大码主要是为了弄懂注解的含义,千万不要使用,因为这种方法太昂贵。
关于反射的代码,不懂 的兄弟姐妹不要着急,后面会讲述的,有不懂的地方,或者我有误的地方,欢迎留言。