第一章 java 基础 - 04注解(下)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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 的效果,但是这种大码主要是为了弄懂注解的含义,千万不要使用,因为这种方法太昂贵。
关于反射的代码,不懂 的兄弟姐妹不要着急,后面会讲述的,有不懂的地方,或者我有误的地方,欢迎留言。

猜你喜欢

转载自blog.csdn.net/weixin_39923324/article/details/82147299