日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android 插件化】“ 插桩式 “ 插件化框架 ( 代理 Activity 组件开发 )

發布時間:2025/6/17 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 插件化】“ 插桩式 “ 插件化框架 ( 代理 Activity 组件开发 ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android 插件化系列文章目錄

【Android 插件化】插件化簡介 ( 組件化與插件化 )
【Android 插件化】插件化原理 ( JVM 內存數據 | 類加載流程 )
【Android 插件化】插件化原理 ( 類加載器 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 原理與實現思路 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 類加載器創建 | 資源加載 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 注入上下文的使用 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 獲取插件入口 Activity 組件 | 加載插件 Resources 資源 )
【Android 插件化】“ 插樁式 “ 插件化框架 ( 運行應用 | 代碼整理 )


文章目錄

  • Android 插件化系列文章目錄
  • 一、加載插件包 dex 的類加載器
  • 二、生命周期回調方法
  • 三、代理 Activity 組件
  • 四、博客資源



參考 【Android 插件化】“ 插樁式 “ 插件化框架 ( 原理與實現思路 ) 中給出的實現思路 , 逐步實現 “ 插樁式 “ 插件化框架 ;

在 【Android 插件化】“ 插樁式 “ 插件化框架 ( 類加載器創建 | 資源加載 ) 博客中 , 開發了 DexClassLoader 類加載器加載插件包 , 并使用 AssetManager 加載插件包資源的模塊 ;

本博客中開發開發本地的 Activity 樁 , 即空殼 Activity , 用于持有插件界面組件 , 并在生命周期中回調插件界面 Activity 組件的對應生命周期方法 ;




一、加載插件包 dex 的類加載器



在 插件化框架 中定義一個代理 Activity , ProxyActivity , 該 Activity 只是個空殼 , 持有從 apk 加載的 PluginActivity 類對象 , 在 ProxyActivity 聲明周期方法中調用對應 PluginActivity 類的生命周期方法

將 ProxyActivity 中要加載的全類名 , 設置在成員屬性中 ;

/*** 被代理的目標 Activity 組件的全類名*/ private String className = "";

如果要使用類加載器加載 插件包 apk 中的 ProxyActivity , 則不能使用應用本身的類加載器 , 插件管理器 PluginManager 中的類加載器已經加載了插件包 apk 中的 dex 文件 , 因此可以獲取到 PluginActivity 字節碼對象 ;

// 創建 DexClassLoader mDexClassLoader = new DexClassLoader(loadPath, // 加載路徑optimizedDirectory.getAbsolutePath(), // apk 解壓緩存目錄null,context.getClassLoader() // DexClassLoader 加載器的父類加載器 );

在支持 插件化的工程中 , " 宿主 " 模塊 和 " 插件 " 模塊 都要依賴該 " 插件化框架 " ;

調用插件化框架中的 PluginManager 單例對象中的類加載器 , 加載插件包 apk 中的 PluginActivity 類對象 ;

/*** 插件化框架核心類*/ public class PluginManager {/*** 類加載器* 用于加載插件包 apk 中的 classes.dex 文件中的字節碼對象*/private DexClassLoader mDexClassLoader;/*** 獲取類加載器* @return*/public DexClassLoader getmDexClassLoader() {return mDexClassLoader;} }

設置 代理界面組件 ProxyActivity 中的類加載器為 插件化框中 中的 插件管理器 PluginManager 中的類加載器 ;

public class ProxyActivity extends AppCompatActivity {/*** 被代理的目標 Activity 組件的全類名*/private String className = "";@Overridepublic ClassLoader getClassLoader() {return PluginManager.getInstance().getmDexClassLoader();} }

這樣就可以在 ProxyActivity 中調用 getClassLoader() 方法獲取插件管理器中的 DexClassLoader , 用于加載插件中的字節碼類對象 ;




二、生命周期回調方法



定義一個接口 , 接口中定義 Activity 組件的生命周期 ;

package com.example.plugin_core;import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent;import androidx.annotation.NonNull;public interface PluginActivityInterface {/*** 綁定代理 Activity* @param proxyActivity*/void attach(Activity proxyActivity);void onCreate(Bundle savedInstanceState);void onStart();void onResume();void onPause();void onStop();void onDestroy();void onSaveInstanceState(Bundle outState);boolean onTouchEvent(MotionEvent event);void onBackPressed();}

定義一個 Activity 基類 BaseActivity , 繼承 AppCompatActivity , 實現了 PluginActivityInterface , 其中涉及到的生命周期函數重復了 , 如 AppCompatActivity 中的 public void onCreate(Bundle savedInstanceState) 方法與 PluginActivityInterface 接口中的 public void onCreate(Bundle savedInstanceState) 方法是重復的 , 這里在每個方法前面加上 @SuppressLint("MissingSuperCall") 注解 , 忽略該報錯 ;

所有的插件包中的 Activity 都要集繼承該 BaseActivity ;

這樣寫的目的是為了方便在代理 Activity 中可以隨意調用插件包中的 Activity 類的生命周期函數 , 這些生命周期函數都是 protected 方法 , 不能直接調用 , 否則每個方法調用時 , 還要先反射修改訪問性 , 才能調用 ;

package com.example.plugin_core;import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;public class BaseActivity extends AppCompatActivity implements PluginActivityInterface {/*** 注入的 Activity*/private Activity that;/*** 注入代理 Activity* 在 ProxyActivity 中將代理 Activity 組件注入進來* @param proxyActivity*/@Overridepublic void attach(Activity proxyActivity) {that = proxyActivity;}@SuppressLint("MissingSuperCall")@Overridepublic void onCreate(Bundle savedInstanceState) {}@SuppressLint("MissingSuperCall")@Overridepublic void onStart() {}@SuppressLint("MissingSuperCall")@Overridepublic void onResume() {}@SuppressLint("MissingSuperCall")@Overridepublic void onPause() {}@SuppressLint("MissingSuperCall")@Overridepublic void onStop() {}@SuppressLint("MissingSuperCall")@Overridepublic void onDestroy() {}@SuppressLint("MissingSuperCall")@Overridepublic void onSaveInstanceState(Bundle outState) {} }


三、代理 Activity 組件



在代理 Activity 組件 ProxyActivity 中 ,

維護兩個成員屬性 ,

/*** 被代理的目標 Activity 組件的全類名*/ private String className = "";

插件包類的 全類名 , 需要通過反射獲取該類的字節碼對象 ;

/*** 插件包中的 Activity 界面組件*/ private PluginActivityInterface pluginActivity;

插件包中的 Activity 組件類 , 借助反射獲取該類 , 在 Activity 的各個聲明周期函數中 , 需要調用該 PluginActivityInterface 的各個對應接口 ;


在 onCreate 方法中 , 先獲取類加載器 , 并反射 插件 Activity 字節碼對象 ; 并使用反射創建 Activity 類對象 ;

// 使用類加載器加載插件中的界面組件 Class<?> clazz = getClassLoader().loadClass(className); // 使用反射創建插件界面組件 Activity Activity activity = (Activity) clazz.newInstance();

判斷插件 Activity 是否是 PluginActivityInterface 類型的 , 如果是強轉為 PluginActivityInterface 類型對象 , 并開始注入上下文 Activity , 在插件類中凡是涉及到調用上下文的地方 , 一律調用該注入的上下文對象 , 也就是代理 ProxyActivity 的上下文 ;

// 判斷 Activity 組件是否是 PluginActivityInterface 接口類型的 if (activity instanceof PluginActivityInterface){// 如果是 PluginActivityInterface 類型 , 則強轉為該類型this.pluginActivity = (PluginActivityInterface) activity;// 上下文注入// 將該 ProxyActivity 綁定注入到 插件包的 PluginActivity 類中// 該 PluginActivity 具有運行的上下文// 一旦綁定注入成功 , 則被代理的 PluginActivity 也具有了上下文pluginActivity.attach(this);// 調用pluginActivity.onCreate(savedInstanceState); }

ProxyActivity 完整代碼示例 :

package com.example.plugin_core;import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity;import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent;/*** 該 Activity 只是個空殼 ;* 主要用于持有從 apk 加載的 Activity 類* 并在 ProxyActivity 聲明周期方法中調用對應 PluginActivity 類的生命周期方法*/ public class ProxyActivity extends AppCompatActivity {/*** 被代理的目標 Activity 組件的全類名*/private String className = "";/*** 插件包中的 Activity 界面組件*/private PluginActivityInterface pluginActivity;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_proxy);// 注意此處的 ClassLoader 類加載器必須是插件管理器中的類加載器try {// 使用類加載器加載插件中的界面組件Class<?> clazz = getClassLoader().loadClass(className);// 使用反射創建插件界面組件 ActivityActivity activity = (Activity) clazz.newInstance();// 判斷 Activity 組件是否是 PluginActivityInterface 接口類型的if (activity instanceof PluginActivityInterface){// 如果是 PluginActivityInterface 類型 , 則強轉為該類型this.pluginActivity = (PluginActivityInterface) activity;// 上下文注入// 將該 ProxyActivity 綁定注入到 插件包的 PluginActivity 類中// 該 PluginActivity 具有運行的上下文// 一旦綁定注入成功 , 則被代理的 PluginActivity 也具有了上下文pluginActivity.attach(this);// 調用pluginActivity.onCreate(savedInstanceState);}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}}@Overrideprotected void onStart() {super.onStart();pluginActivity.onStart();}@Overrideprotected void onResume() {super.onResume();pluginActivity.onResume();}@Overrideprotected void onPause() {super.onPause();pluginActivity.onPause();}@Overrideprotected void onStop() {super.onStop();pluginActivity.onStop();}@Overrideprotected void onDestroy() {super.onDestroy();pluginActivity.onDestroy();}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);pluginActivity.onSaveInstanceState(outState);}@Overridepublic boolean onTouchEvent(MotionEvent event) {super.onTouchEvent(event);return pluginActivity.onTouchEvent(event);}@Overridepublic void onBackPressed() {super.onBackPressed();pluginActivity.onBackPressed();}@Overridepublic ClassLoader getClassLoader() {return PluginManager.getInstance().getmDexClassLoader();} }



四、博客資源



博客資源 :

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

總結

以上是生活随笔為你收集整理的【Android 插件化】“ 插桩式 “ 插件化框架 ( 代理 Activity 组件开发 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。