android面试题-注解框架内部实现原理

Android程序员面试宝典

自定义控件

  • 一分钟实现贴纸功能
  • 一分钟实现TextView高亮
  • 一分钟实现新手引导页
  • 一分钟实现ViewPager卡片
  • 一分钟实现轮播图
  • 一分钟实现GridView拖拽
  • 一分钟实现底部导航栏
  • 一分钟实现底部FragmentTabhost
  • 一分钟实现多张图片选择
  • 一分钟实现仿美拍直播的点赞动画
  • 一分钟实现高仿今日头条视频列表
  • 一分钟实现购物车加减控件
  • 一分钟实现省市县三级联动
  • 一分钟实现二维码生成和扫描
  • 一分钟实现沉浸式状态栏
  • 一分钟实现图片裁剪
  • 一分钟实现视频弹幕
  • 一分钟实现图片缩放
  • 一分钟实现旋转选择器
  • 一分钟实现ofo小黄车的引导界面
  • 一分钟实现自定义ImageView外貌
  • 一分钟实现向左拖拽跳转详情页
  • 一分钟实现QQ首页动画特效
  • 一分钟实现ViewPager上下滑动

联网

  • 一分钟学会Retrofit并且进行实战
  • 一分钟实现OkHttp3

工具

  • 一分钟实现RecyclerView
  • 一分钟实现H5和Android通信
  • 一分钟实现pinyin4j
  • 一分钟实现分析内存泄漏

数据库

  • 一分钟实现LitePal数据库
  • 一分钟实现ormlite数据库
  • 一分钟实现GreenDao数据库

源码分析相关面试题

  • Volley源码分析
  • 注解框架实现原理
  • okhttp3.0源码分析
  • onSaveInstanceState源码分析
  • 静默安装和源码编译

Activity相关面试题

  • 保存Activity的状态
  • 深刻剖析activity启动模式(一)
  • 深刻剖析activity启动模式(二)
  • 深刻剖析activity启动模式(三)
  • Activity Task和Process之间的关系
  • 源码分析service开启Activity抛异常?activity不会抛异常
  • Activity优雅退出
  • onCreate源码分析

Service相关面试题

  • IntentService源码分析
  • Service是否在main thread中执行, service里面是否能执行耗时的操作?
  • Service不死之身

与XMPP相关面试题

  • XMPP协议优缺点
  • 极光消息推送原理

与性能优化相关面试题

  • 内存泄漏和内存溢出区别
  • UI优化和线程池实现原理
  • 代码优化
  • 内存性能分析
  • 内存泄漏检测
  • App启动优化
  • 与IPC机制相关面试题

与登录相关面试题

  • oauth认证协议原理
  • token产生的意义
  • 微信扫一扫实现原理

与开发相关面试题

  • 迭代开发的时候如何向前兼容新旧接口
  • 手把手教你如何解决as jar包冲突
  • context的原理分析
  • 解决ViewPager.setCurrentItem中间很多页面切换方案
  • 字体适配
  • 软键盘适配
  • 机型适配,例如三星、小米、华为、魅族等
  • CardView 设置水波纹效果

与人事相关面试题

  • 人事面试宝典

本文配套视频:

  • 配套视频

注解框架实现原理,手写Xutils实现自己的注解框架

初级程序员使用别人的框架,中级程序员不仅会使用别人的框架还知道内部的实现原理,高级程序员则按需编写自己的框架。添加该模块的目的就是想提交大家的逼格,让大家养成一个动手编写“自主知识产权”框架的意识。

一. 编写 Xutils框架

业界比较出名的基于完全注解方式就可以进行 UI 绑定和事件绑定,无需 findViewById 和 setClickListener 等的IOC(Inverse Of Control 控制反转,就是将 UI 的初始化和事件绑定的“权利”交给框架来完成)框架有:

Xutils使用如下:

android面试题-注解框架内部实现原理_第1张图片
android面试题-注解框架内部实现原理_第2张图片

会出现如下代码:

   @BindView(R.id.button01)
    Button mButton01;
    @BindView(R.id.button02)
    Button mButton02;
    @BindView(R.id.button03)
    Button mButton03;

        @butterknife.OnClick({R.id.button01, R.id.button02, R.id.button03})
    public void onClick(View view) {
        switch (view.getId()) {
          case R.id.button01:
          Toast.makeText(this, "butterknife-button01", Toast.LENGTH_SHORT).show();
                break;
          case R.id.button02:
           Toast.makeText(this, "butterknife-button02", Toast.LENGTH_SHORT).show();
                break;
          case R.id.button03:
          Toast.makeText(this, "butterknife-button03", Toast.LENGTH_SHORT).show();
                break;
        }
    }

点击每个按钮会弹出响应的Toast,如下:

android面试题-注解框架内部实现原理_第3张图片

这个就是ButterKnife的用法。

接下来,我们开始编写自己的框架实现 findViewById 和 setOnClickListener 功能。

  1. 编写自定义注解类 ViewInject 和 Click;

ViewInject 注解类用于添加在 Filed 上。Click 注解类用于添加到 Method 上。

【文件】ViewInject.java

/**
* @Retention 用于声明该注解生效的生命周期,有三个枚举值可以选择
* 1. RetentionPolicy.SOURCE 注释只保留在源码上面,编译成class的时候自动被编译器抹除 * 2. RetentionPolicy.CLASS 注释只保留到字节码上面,VM加载字节码时自动抹除 * 3. RetentionPolicy.RUNTIME 注释永久保留,可以被VM加载时加载到内存中 * 注意:由于我们的目的是想在VM运行时对Filed上的该注解进行反射操作,因此Retention值必须设置为RUNTIME * * @Target 用于指定该注解可以声明在哪些成员上面,常见的值有FIELD和Method, 由于我们的当前注解类是想声明在Filed上面 * 因此这里设置为ElementType.FIELD。 * 注意:如果@Target值不设置,则默认可以添加到任何元素上,不推荐这么写。 * * @interface 是声明注解类的组合关键字。 */ @Target({java.lang.annotation.ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface ViewInject { public abstract int value(); }

【文件】Click.java

@Target({java.lang.annotation.ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick
{
    public abstract int[] value();
}

编写核心方法 ViewUtilsTest.inject(Ativity);

public class ViewUtilsTest {
    public static void inject(final Activity activity)
    {
        /**
         * 通过字节码获取activity类中所有的字段,在获取Field的时候一定要使用
         * getDeclaredFields(),
         * 因为只有该方法才能获取到任何权限修饰的Filed,包括私有的。
         */

        Class clazz = activity.getClass();
        Field[] declaredFields = clazz.getDeclaredFields();
        //一个Activity中可能有多个Field,因此遍历。
        for (int i = 0; i < declaredFields.length; i++) {
            Field field = declaredFields[i];
            //设置为可访问,暴力反射,就算是私有的也能访问到
            field.setAccessible(true);
         //获取到字段上面的注解对象
         ViewInject annotation = (ViewInject)field.getAnnotation(ViewInject.class);
            //一定对annotation是否等于null进行判断,因为并不是所有Filed上都有我们想要的注解
            if (annotation == null)
            {
                continue;
            }
            //获取注解中的值
            int id = annotation.value();
            //获取控件
            View view = activity.findViewById(id);

            try
            {
                //将该控件设置给field对象
                field.set(activity, view);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

        }
        //获取所有的方法(私有方法也可以获取到)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (int i = 0; i < declaredMethods.length; i++) {
            final Method method = declaredMethods[i];
            //获取方法上面的注解
            OnClick annotation = (OnClick)method.getAnnotation(OnClick.class);
            if (annotation == null) {
                //如果该方法上没有注解,循环下一个
                continue;
            }
            //获取注解中的数据,因为可以给多个button绑定点击事件,因此定义注解类时使用的是int[]作为数据类型。
            int[] value = annotation.value();
            for (int j = 0; j < value.length; j++) {
                int id = value[j];

                final View button = activity.findViewById(id);

                button.setOnClickListener(new View.OnClickListener()
                {
                    public void onClick(View v)
                    {
                        try
                        {
                            //反射调用用户指定的方法
                           method.invoke(activity,button);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    }
}

咱们自己的注解框架就实现好了,效果如下:

android面试题-注解框架内部实现原理_第4张图片
  • 欢迎关注微信公众号,长期推荐技术文章和技术视频

微信公众号名称:Android干货程序员

android面试题-注解框架内部实现原理_第5张图片

你可能感兴趣的:(android面试题-注解框架内部实现原理)