日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

【Android 插件化】Hook 插件化框架 ( 加载插件包资源 )

發(fā)布時(shí)間:2025/6/17 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 插件化】Hook 插件化框架 ( 加载插件包资源 ) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Android 插件化系列文章目錄

【Android 插件化】插件化簡介 ( 組件化與插件化 )
【Android 插件化】插件化原理 ( JVM 內(nèi)存數(shù)據(jù) | 類加載流程 )
【Android 插件化】插件化原理 ( 類加載器 )

【Android 插件化】“ 插樁式 “ 插件化框架 ( 原理與實(shí)現(xiàn)思路 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 類加載器創(chuàng)建 | 資源加載 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 注入上下文的使用 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 獲取插件入口 Activity 組件 | 加載插件 Resources 資源 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 運(yùn)行應(yīng)用 | 代碼整理 )

【Android 插件化】Hook 插件化框架 ( Hook 技術(shù) | 代理模式 | 靜態(tài)代理 | 動態(tài)代理 )
【Android 插件化】Hook 插件化框架 ( Hook 實(shí)現(xiàn)思路 | Hook 按鈕點(diǎn)擊事件 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動過程 | 靜態(tài)代理 )

【Android 插件化】Hook 插件化框架 ( 從 Hook 應(yīng)用角度分析 Activity 啟動流程 一 | Activity 進(jìn)程相關(guān)源碼 )
【Android 插件化】Hook 插件化框架 ( 從 Hook 應(yīng)用角度分析 Activity 啟動流程 二 | AMS 進(jìn)程相關(guān)源碼 | 主進(jìn)程相關(guān)源碼 )

【Android 插件化】Hook 插件化框架 ( hook 插件化原理 | 插件包管理 )
【Android 插件化】Hook 插件化框架 ( 通過反射獲取 “插件包“ 中的 Element[] dexElements )
【Android 插件化】Hook 插件化框架 ( 通過反射獲取 “宿主“ 應(yīng)用中的 Element[] dexElements )
【Android 插件化】Hook 插件化框架 ( 合并 “插件包“ 與 “宿主“ 中的 Element[] dexElements | 設(shè)置合并后的 Element[] 數(shù)組 )
【Android 插件化】Hook 插件化框架 ( 創(chuàng)建插件應(yīng)用 | 拷貝插件 APK | 初始化插件包 | 測試插件 DEX 字節(jié)碼 )

【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動流程 | Hook 點(diǎn)分析 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動流程 | 反射獲取 IActivityManager 對象 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動流程 | AMS 啟動前使用動態(tài)代理替換掉插件 Activity 類 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動流程 | 主線程創(chuàng)建 Activity 實(shí)例之前使用插件 Activity 類替換占位的組件 )

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

【Android 插件化】Hook 插件化框架 ( 插件包資源加載 )


文章目錄

  • Android 插件化系列文章目錄
  • 前言
  • 一、加載插件包資源文件
    • 1、反射 AssetManager 類并創(chuàng)建實(shí)例對象
    • 2、反射 AssetManager 的 addAssetPath 方法并調(diào)用
    • 3、創(chuàng)建 Resources
  • 二、自定義 Application 中設(shè)置插件資源
  • 三、插件 Activity 組件中設(shè)置插件資源
  • 四、博客資源

前言

【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動流程 | AMS 啟動前使用動態(tài)代理替換掉插件 Activity 類 )
【Android 插件化】Hook 插件化框架 ( Hook Activity 啟動流程 | 主線程創(chuàng)建 Activity 實(shí)例之前使用插件 Activity 類替換占位的組件 )

博客中 , 基本已經(jīng)完成了插件 Activity 的實(shí)例化操作 , 已經(jīng)可以啟動插件 Activity , 只剩下資源文件沒有獲取 ;

本博客開始加載插件包中的資源文件 ;





一、加載插件包資源文件



在插件包中的 Activity , 如果加載 R.layout.activity_main , 拿到的是 “宿主” 應(yīng)用中的資源 , 無法拿到插件包中的資源 ;


1、反射 AssetManager 類并創(chuàng)建實(shí)例對象


反射 AssetManager 類 , 并創(chuàng)建 AssetManager 實(shí)例對象 ;

// 使用反射工具類進(jìn)行鏈?zhǔn)秸{(diào)用 , 創(chuàng)建 AssetManager 對象AssetManager assetManager = Reflector.on(AssetManager.class).newInstance();

涉及到的反射工具類內(nèi)容 : 上述代碼使用了上一篇博客 【Android 插件化】Hook 插件化框架 ( 反射工具類 | 反射常用操作整理 ) 中的 反射工具類 , 涉及到的反射代碼如下 :

/*** 封裝反射相關(guān)邏輯的工具類* 該封裝類會維持鏈?zhǔn)秸{(diào)用*/ public class Reflector {/*** 反射某個(gè)類的入口方法** @param type 要反射的類* @return*/public static Reflector on(Class<?> type) {Reflector reflector = new Reflector();reflector.mClass = type;return reflector;}/*** 創(chuàng)建 mClass 類型的實(shí)例對象* @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;}} }

2、反射 AssetManager 的 addAssetPath 方法并調(diào)用


通過反射獲取 AssetManager 的 addAssetPath 方法 , 方法的參數(shù)是 String 類型 ;

執(zhí)行該方法 , 傳入當(dāng)前插件包 APK 的路徑 ;

// 獲取插件包 APK 文件路徑 , 加載該 APK 下的資源// /data/user/0/com.example.plugin_hook/files/plugin.apkString pluginPath = mBase.getFilesDir() + "/plugin.apk";// 使用反射調(diào)用 AssetManager 中的 addAssetPath 方法 , 傳入 APK 插件包的路徑// addAssetPath 方法的參數(shù)為 /data/user/0/com.example.plugin_hook/files/plugin.apkReflector.on(assetManager).method("addAssetPath", String.class).call(pluginPath);

涉及到的反射工具類內(nèi)容 : 上述代碼使用了上一篇博客 【Android 插件化】Hook 插件化框架 ( 反射工具類 | 反射常用操作整理 ) 中的 反射工具類 , 涉及到的反射代碼如下 :

/*** 封裝反射相關(guān)邏輯的工具類* 該封裝類會維持鏈?zhǔn)秸{(diào)用*/ public class Reflector {/*** 反射某個(gè)類的入口方法** @param type 要反射的類* @return*/public static Reflector on(Class<?> type) {Reflector reflector = new Reflector();reflector.mClass = type;return reflector;}/*** 反射某個(gè)類的入口方法** @param className 要反射的類名* @return*/public static Reflector on(String className) {try {return on(Class.forName(className));} catch (ClassNotFoundException e) {e.printStackTrace();return null;}}/*** 反射某個(gè)類的入口方法** @param object 反射類對應(yīng)的實(shí)例對象* @return*/public static Reflector on(Object object) {return on(object.getClass()).with(object);}/*** 反射類中的某個(gè)方法** @param name* @param args* @return*/public Reflector method(String name, Class<?>... args) {mMethod = findMethod(name, args);mMethod.setAccessible(true);return this;}/*** 根據(jù)方法名 和 參數(shù)名稱 , 查找 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;}}/*** 調(diào)用 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;}} }

3、創(chuàng)建 Resources


創(chuàng)建 Resources , 傳入 AssetManager 對象作為主要參數(shù) , 其它參數(shù)都可以從應(yīng)用的 Resources 中獲取 ;

// 創(chuàng)建 Resources 并返回return mResources = new Resources(assetManager,mBase.getResources().getDisplayMetrics(),mBase.getResources().getConfiguration()



二、自定義 Application 中設(shè)置插件資源



加載到插件資源后 , 重寫 Application 的 public Resources getResources() 方法 , 返回插件包方法 ;

@Overridepublic Resources getResources() {if (pluginResources != null)return pluginResources;return super.getResources();}

完整代碼示例 :

package com.example.plugin_hook;import android.app.Application; import android.content.res.Resources; import android.util.Log;import java.io.File;import kim.hsl.plugin.PluginManager;public class MyApplication extends Application {private static final String TAG = "plugin_MyApplication";/*** 插件資源*/private Resources pluginResources;@Overridepublic void onCreate() {super.onCreate();// 如果已經(jīng)存在文件, 先刪除 , 防止拷貝過程中出錯(cuò)File pluginFile = new File(getFilesDir() + "/plugin.apk");if (pluginFile.exists()){pluginFile.delete();}// 先將 assets 中的插件包拷貝到 內(nèi)置存儲中CommandUtils.copyAssets2File(this,"plugin.apk",getFilesDir() + "/plugin.apk");// 將文件從 assets/plugin.apk 拷貝到 /data/user/0/com.example.plugin_hook/files/plugin.apkLog.i(TAG, "將文件從 assets/plugin.apk 拷貝到 " + getFilesDir() + "/plugin.apk");// 初始化插件包PluginManager.getInstance(this).init();Log.i(TAG, "插件化 初始化完畢");// 設(shè)置插件包中的資源文件pluginResources = PluginManager.getInstance(this).getmResources();}@Overridepublic Resources getResources() {if (pluginResources != null)return pluginResources;return super.getResources();} }



三、插件 Activity 組件中設(shè)置插件資源



在 Activity 中重寫 public Resources getResources() 方法 , 核心是返回插件資源 ;

@Overridepublic Resources getResources() {if (getApplication() != null && getApplication().getResources() != null) {return getApplication().getResources();}return super.getResources();}

完整代碼示例 :

package com.example.plugin;import androidx.appcompat.app.AppCompatActivity;import android.app.Activity; import android.content.res.Resources; import android.os.Bundle; import android.util.Log;public class MainActivity extends Activity {private static final String TAG = "plugin_MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.i("plugin", "啟動了插件 Activity");}public void log(){Log.i(TAG, "Plugin MainActivity");}@Overridepublic Resources getResources() {if (getApplication() != null && getApplication().getResources() != null) {return getApplication().getResources();}return super.getResources();} }



四、博客資源



博客資源 :

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

總結(jié)

以上是生活随笔為你收集整理的【Android 插件化】Hook 插件化框架 ( 加载插件包资源 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。