Android 插件化系列文章目录

【Android 插件化】插件化简介 ( 组件化与插件化 )
【Android 插件化】插件化原理 ( JVM 内存数据 | 类加载流程 )
【Android 插件化】插件化原理 ( 类加载器 )

【Android 插件化】“ 插桩式 “ 插件化框架 ( 原理与实现思路 )
【Android 插件化】“ 插桩式 “ 插件化框架 ( 类加载器创建 | 资源加载 )
【Android 插件化】“ 插桩式 “ 插件化框架 ( 注入上下文的使用 )
【Android 插件化】“ 插桩式 “ 插件化框架 ( 获取插件入口 Activity 组件 | 加载插件 Resources 资源 )
【Android 插件化】“ 插桩式 “ 插件化框架 ( 运行应用 | 代码整理 )

【Android 插件化】Hook 插件化框架 ( Hook 技术 | 代理模式 | 静态代理 | 动态代理 )
【Android 插件化】Hook 插件化框架 ( Hook 实现思路 | Hook 按钮点击事件 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动过程 | 静态代理 )

【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 一 | Activity 进程相关源码 )
【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 二 | AMS 进程相关源码 | 主进程相关源码 )

【Android 插件化】Hook 插件化框架 ( hook 插件化原理 | 插件包管理 )
【Android 插件化】Hook 插件化框架 ( 通过反射获取 “插件包“ 中的 Element[] dexElements )
【Android 插件化】Hook 插件化框架 ( 通过反射获取 “宿主“ 应用中的 Element[] dexElements )
【Android 插件化】Hook 插件化框架 ( 合并 “插件包“ 与 “宿主“ 中的 Element[] dexElements | 设置合并后的 Element[] 数组 )
【Android 插件化】Hook 插件化框架 ( 创建插件应用 | 拷贝插件 APK | 初始化插件包 | 测试插件 DEX 字节码 )

【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 反射获取 IActivityManager 对象 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | AMS 启动前使用动态代理替换掉插件 Activity 类 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )

【Android 插件化】Hook 插件化框架 ( 反射工具类 | 反射常用操作整理 )


文章目录

  • Android 插件化系列文章目录
  • 前言
  • 一、成员变量
  • 二、反射工具类入口方法
  • 三、反射 Field 相关方法
    • 1、反射 Field 字段
    • 2、反射获取 Field 对应实例
    • 3、反射设置 Field 对应实例
  • 四、反射 Method 相关方法
    • 1、反射 Method 方法
    • 2、反射调用 Method 方法
  • 五、完整反射工具类代码示例
  • 六、博客资源

前言

在前面的几篇博客中 , 大量使用到了反射操作 , 使用反射时 , 需要处理大量的异常信息 , 很麻烦 ;

在本篇博客中 , 封装一个反射工具类 , 用于反射的常用操作 , 如 反射类 , 字段 , 方法 , 实例化对象 , 获取 / 设置 字段 , 执行方法 等操作 ;

一、成员变量


将反射涉及到的 类 , 实例对象 , 字段 , 方法 , 设置为反射工具类的成员变量 ;

    /*** 反射的类型*/private Class<?> mClass;/*** 反射针对的实例对象* 如获取 Object 某个字段的值*/private Object mCaller;/*** 反射的字段*/private Field mField;/*** 反射的方法*/private Method mMethod;

二、反射工具类入口方法


入口方法主要是设置 反射类 / 对象 ;

    /*** 反射某个类的入口方法** @param type 要反射的类* @return*/public static Reflector on(Class<?> type) {Reflector reflector = new Reflector();reflector.mClass = type;return reflector;}/*** 反射某个类的入口方法** @param className 要反射的类名* @return*/public static Reflector on(String className) {try {return on(Class.forName(className));} catch (ClassNotFoundException e) {e.printStackTrace();return null;}}/*** 反射某个类的入口方法** @param object 反射类对应的实例对象* @return*/public static Reflector on(Object object) {return on(object.getClass()).with(object);}/*** 设置反射对应的实例对象** @param object* @return*/public Reflector with(Object object) {mCaller = object;return this;}

三、反射 Field 相关方法


1、反射 Field 字段

反射某字段 :

    /*** 反射类中的某个字段** @param name 要反射的字段名称* @return*/public Reflector field(String name) {mField = findField(name);mField.setAccessible(true);return this;}/*** 查找字段名称*      首先在本类中查找*          如果找到直接返回字段*          如果在本类中没有找到 , 就去遍历它的父类 , 尝试在父类中查找该字段*              如果有父类 , 则在父类中查找*                  如果在父类中找到 , 返回该字段*                  如果在父类中没有找到 , 则返回空*              如果没有父类 , 返回空** 尽量传具体的正确的类 , 不要传子类* @param fieldName* @return*/private Field findField(String fieldName) {try {// 首先在本类中查找 , 如果找到直接返回字段return mClass.getDeclaredField(fieldName);} catch (NoSuchFieldException e) {// 如果在本类中没有找到 , 就去遍历它的父类 , 尝试在父类中查找该字段for (Class<?> clazz = mClass; clazz != null; clazz = clazz.getSuperclass()) {try {// 如果在父类中找到 , 返回该字段return clazz.getDeclaredField(fieldName);} catch (NoSuchFieldException ex) {// 如果在父类中没有找到 , 则返回空return null;}}// 如果没有父类, 则返回空return null;}}

2、反射获取 Field 对应实例

    /*** 获取 mCaller 对象中的 mField 属性值** @return*/public Object get() {try {return mField.get(mCaller);} catch (IllegalAccessException e) {e.printStackTrace();return null;}}

3、反射设置 Field 对应实例

    /*** 设置 mCaller 对象中的 mField 属性值** @param value* @return 链式调用 , 返回 Reflector*/public Reflector set(Object value) {try {mField.set(mCaller, value);} catch (IllegalAccessException e) {e.printStackTrace();}return this;}

四、反射 Method 相关方法


1、反射 Method 方法

    /*** 反射类中的某个方法** @param name* @param args* @return*/public Reflector method(String name, Class<?>... args) {mMethod = findMethod(name, args);mMethod.setAccessible(true);return this;}/*** 根据方法名 和 参数名称 , 查找 Method 方法*      首先在本类中查找*          如果找到直接返回字段*          如果在本类中没有找到 , 就去遍历它的父类 , 尝试在父类中查找该字段*              如果有父类 , 则在父类中查找*                  如果在父类中找到 , 返回该字段*                  如果在父类中没有找到 , 则返回空*              如果没有父类 , 返回空** 尽量传具体的正确的类 , 不要传子类* @param name* @param args* @return*/private Method findMethod(String name, Class<?>... args) {try {// 首先在本类中查找 , 如果找到直接返回方法return mClass.getDeclaredMethod(name, args);} catch (NoSuchMethodException e) {// 如果在本类中没有找到 , 就去遍历它的父类 , 尝试在父类中查找该方法for (Class<?> cls = mClass; cls != null; cls = cls.getSuperclass()) {try {// 如果在父类中找到 , 返回该字段return cls.getDeclaredMethod(name);} catch (NoSuchMethodException ex) {// 如果在父类中没有找到 , 则返回空return null;}}// 如果没有父类, 则返回空return null;}}

2、反射调用 Method 方法

    /*** 调用 mCaller 的 mMethod 方法** @param args* @param <T>* @return*/public <T> T call(Object... args) {try {return (T) mMethod.invoke(mCaller, args);} catch (IllegalAccessException e) {e.printStackTrace();return null;} catch (InvocationTargetException e) {e.printStackTrace();return null;}}

五、完整反射工具类代码示例


package kim.hsl.plugin;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;/*** 封装反射相关逻辑的工具类* 该封装类会维持链式调用*/
public class Reflector {/*** 反射的类型*/private Class<?> mClass;/*** 反射针对的实例对象* 如获取 Object 某个字段的值*/private Object mCaller;/*** 反射的字段*/private Field mField;/*** 反射的方法*/private Method mMethod;/*** 反射某个类的入口方法** @param type 要反射的类* @return*/public static Reflector on(Class<?> type) {Reflector reflector = new Reflector();reflector.mClass = type;return reflector;}/*** 反射某个类的入口方法** @param className 要反射的类名* @return*/public static Reflector on(String className) {try {return on(Class.forName(className));} catch (ClassNotFoundException e) {e.printStackTrace();return null;}}/*** 反射某个类的入口方法** @param object 反射类对应的实例对象* @return*/public static Reflector on(Object object) {return on(object.getClass()).with(object);}/*** 设置反射对应的实例对象** @param object* @return*/public Reflector with(Object object) {mCaller = object;return this;}/*** 创建 mClass 类型的实例对象* @param <T>* @return* @throws Exception*/public <T> T newInstance() {try {return (T) mClass.newInstance();} catch (IllegalAccessException e) {e.printStackTrace();return null;} catch (InstantiationException e) {e.printStackTrace();return null;}}/*** 反射类中的某个字段** @param name 要反射的字段名称* @return*/public Reflector field(String name) {mField = findField(name);mField.setAccessible(true);return this;}/*** 查找字段名称*      首先在本类中查找*          如果找到直接返回字段*          如果在本类中没有找到 , 就去遍历它的父类 , 尝试在父类中查找该字段*              如果有父类 , 则在父类中查找*                  如果在父类中找到 , 返回该字段*                  如果在父类中没有找到 , 则返回空*              如果没有父类 , 返回空** 尽量传具体的正确的类 , 不要传子类* @param fieldName* @return*/private Field findField(String fieldName) {try {// 首先在本类中查找 , 如果找到直接返回字段return mClass.getDeclaredField(fieldName);} catch (NoSuchFieldException e) {// 如果在本类中没有找到 , 就去遍历它的父类 , 尝试在父类中查找该字段for (Class<?> clazz = mClass; clazz != null; clazz = clazz.getSuperclass()) {try {// 如果在父类中找到 , 返回该字段return clazz.getDeclaredField(fieldName);} catch (NoSuchFieldException ex) {// 如果在父类中没有找到 , 则返回空return null;}}// 如果没有父类, 则返回空return null;}}/*** 获取 mCaller 对象中的 mField 属性值** @return*/public Object get() {try {return mField.get(mCaller);} catch (IllegalAccessException e) {e.printStackTrace();return null;}}/*** 设置 mCaller 对象中的 mField 属性值** @param value* @return 链式调用 , 返回 Reflector*/public Reflector set(Object value) {try {mField.set(mCaller, value);} catch (IllegalAccessException e) {e.printStackTrace();}return this;}/*** 反射类中的某个方法** @param name* @param args* @return*/public Reflector method(String name, Class<?>... args) {mMethod = findMethod(name, args);mMethod.setAccessible(true);return this;}/*** 根据方法名 和 参数名称 , 查找 Method 方法*      首先在本类中查找*          如果找到直接返回字段*          如果在本类中没有找到 , 就去遍历它的父类 , 尝试在父类中查找该字段*              如果有父类 , 则在父类中查找*                  如果在父类中找到 , 返回该字段*                  如果在父类中没有找到 , 则返回空*              如果没有父类 , 返回空** 尽量传具体的正确的类 , 不要传子类* @param name* @param args* @return*/private Method findMethod(String name, Class<?>... args) {try {// 首先在本类中查找 , 如果找到直接返回方法return mClass.getDeclaredMethod(name, args);} catch (NoSuchMethodException e) {// 如果在本类中没有找到 , 就去遍历它的父类 , 尝试在父类中查找该方法for (Class<?> cls = mClass; cls != null; cls = cls.getSuperclass()) {try {// 如果在父类中找到 , 返回该字段return cls.getDeclaredMethod(name);} catch (NoSuchMethodException ex) {// 如果在父类中没有找到 , 则返回空return null;}}// 如果没有父类, 则返回空return null;}}/*** 调用 mCaller 的 mMethod 方法** @param args* @param <T>* @return*/public <T> T call(Object... args) {try {return (T) mMethod.invoke(mCaller, args);} catch (IllegalAccessException e) {e.printStackTrace();return null;} catch (InvocationTargetException e) {e.printStackTrace();return null;}}
}

六、博客资源


博客资源 :

  • GitHub : https://github.com/han1202012/Plugin_Hook

【Android 插件化】Hook 插件化框架 ( 反射工具类 | 反射常用操作整理 )相关推荐

  1. 反射工具类,如斯优雅

    Foreword 反射的作用我在这就不多说了,每次用到反射都是那么一坨代码丢进去,总是让人觉得很不优雅,如今有了我这个反射工具类,那么大家就可以一句话优雅地来完成反射的工作,该工具类是站在 jOOR ...

  2. Android :RxTools一款强大实用的工具类集合

    QQ群 668524118,欢迎加入交流! Android开发人员不得不收集的工具类集合 | 支付宝支付 | 微信支付(统一下单) | 微信分享 | 一键集成UCrop选择圆形头像 | 一键集成二维码 ...

  3. 反射工具类 java_Java反射工具类

    importjava.lang.reflect.Field;importjava.lang.reflect.Method;/*** Java反射工具类 * 提供以下几个功能: * 1. 取最简类名 * ...

  4. 反射工具类ReflectionUtils

    为什么80%的码农都做不了架构师?>>>    package net.pm.common.toolkit;import java.lang.reflect.Field; impor ...

  5. android语音播放工具类,Android开发之MediaPlayer多媒体(音频,视频)播放工具类

    本文实例讲述了Android开发之MediaPlayer多媒体(音频,视频)播放工具类.分享给大家供大家参考,具体如下: package com.android.imooc.chat; import ...

  6. 【java reflection】反射工具类总结

    这段时间公司搞封闭开发,做一个联通总部的客服系统项目,是基于springboot的.在开发工程中遇到一个页面datagrid数据排序的功能,因为有多个表的数据都要用到排序功能,于是我就写了一个排序功能 ...

  7. 自定义MVC框架之工具类-图像处理类

    截止目前已经改造了4个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 自定义MVC框架之工具类-文件上传类 图像处理类: 1,图片加水印处理( ...

  8. Android - 分转元、元转分 金额工具类

    说明: Android涉及到的金额分转元.元转分,写成工具类做记录使用. 需求: 1.元转分: 可传入字符串或者long型(隐式转换为long型也可)整数. 若传入为字符串,则通过替换小数点的方式转换 ...

  9. 反射工具类Reflections

    import java.lang.reflect.*;/*** 反射工具类.* * 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实 ...

最新文章

  1. mysql 当前id前后几个,使用mysql选择id前后的行
  2. 为 Hyper-V 配置外部网络
  3. Ardino基础教程 10_光控声音
  4. HTML5 浏览器支持(怎么样让低版本浏览器支持html5?)
  5. SAP C4C url Mashup的跳转工作原理 - 新的浏览器窗口是如何打开的
  6. YBTOJ:前缀数组(KMP)
  7. 服务器c盘显示0字节可用,c盘0字节可用怎么解决 c盘0字节可用处理方法
  8. 自动布局和view 设置frame同时有效
  9. pypi 镜像使用帮助——临时使用镜像网站
  10. Linux现在已主导Azure
  11. oracle视频教程11g入门运维DBA性能优化OCP培训SQL数据库在线课程
  12. PART 3.3 风控建模卡方分箱计算篇
  13. 基于STM32的人体红外测温
  14. 智能营销模型-Uplift Model详解及Python使用
  15. 网站劫持原理及分析网站被劫持了有几种解决方法
  16. 自动驾驶技术——初学者笔记1:自动驾驶分级
  17. 金融伦理学(Financial Ethcs)笔记
  18. word中编号样式库内找不到带圈编号的解决方案
  19. 任正非“互联网思维”如是说
  20. proxychans的使用

热门文章

  1. 如何使用Microsoft技术栈
  2. 面向接口编程详解(一)—— 思想基础
  3. .net Redis使用公共方法引用CSRedisCore
  4. vue中使用elmentUI的Upload组件提交文件和后台接收
  5. 从ftp获取文件并生成压缩包
  6. 8.使用hydra对端口进行爆破
  7. demo:a spreadsheet-like application
  8. 【loj6342】跳一跳 期望dp
  9. 跟我学JAVA / 第三课:Java流程控制与数组
  10. C# 字段 属性 方法 三霸主齐上阵