【Android 插件化】Hook 插件化框架 ( 反射工具类 | 反射常用操作整理 )
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 插件化框架 ( 反射工具类 | 反射常用操作整理 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 插件化】Hook 插件
- 下一篇: 【Android 插件化】Hook 插件