<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # 插件化實現 ## 類加載 ### java 中的 ClassLoader BootstrapClassLoader 負責加載 JVM 運行時的核心類,比如?JAVA\_HOME/lib/rt.jar?等等。 ExtensionClassLoader 負責加載 JVM 的擴展類,比如?JAVA\_HOME/lib/ext?下面的 jar 包。 AppClassLoader 負責加載 classpath 里的 jar 包和目錄。 ### android 中的 ClassLoader BootClassLoader <- PathClassLoader 在這里,我們統稱 dex 文件,包含 dex 的 apk 文件以及 jar 文件為 dex 文件?PathClassLoader?用來加載系統類和應用程序類,可以加載已經安裝的 apk 目錄下的 dex 文件。 DexClassLoader?用來加載 dex 文件,可以從存儲空間加載 dex 文件。 我們在插件化中一般使用的是?DexClassLoader。 ~~~ //?從?assets?中拿出插件?apk?放到內部存儲空間 private?fun?extractPlugin()?{ ????var?inputStream?=?assets.open("plugin.apk") ????File(filesDir.absolutePath,?"plugin.apk").writeBytes(inputStream.readBytes()) } private?fun?init()?{ ????extractPlugin() ????pluginPath?=?File(filesDir.absolutePath,?"plugin.apk").absolutePath ????nativeLibDir?=?File(filesDir,?"pluginlib").absolutePath ????dexOutPath?=?File(filesDir,?"dexout").absolutePath ????//?生成?DexClassLoader?用來加載插件類 //pluginPath?是需要加載的?dex / apk / jar?文件路徑。 //dexOutPath?是 dex 優化后存放的位置,在 ART 上,會執行 oat 對 dex 進行優化,生成機器碼,這里就是存放優化后的 odex 文件的位置。 //librarySearchPath?是 native 依賴的位置。 parent?就是父類加載器,默認會先從 parent 加載對應的 ????pluginClassLoader?=?DexClassLoader(pluginPath,?dexOutPath,?nativeLibDir,?this::class.java.classLoader) } ~~~ ### 雙親委派 每一個 ClassLoader 中都有一個 parent 對象,代表的是父類加載器,在加載一個類的時候,會先使用父類加載器去加載,如果在父類加載器中沒有找到,自己再進行加載,如果 parent 為空,那么就用系統類加載器來加載。 ## activity的hook 方法1、我們手動去調用插件 Activity 的生命周期。 方法2、欺騙系統,讓系統以為 Activity 是注冊在 Manifest 中的。 | 現方法 | 優點 | 缺點 | | --- | --- | --- | | 手動調用 | 1\. 比較穩定,不需要 hook 系統實現 2. 實現相對簡單,不需要對系統內部實現做過多了解 | 通過反射效率太低,通過接口需要實現的方法數量很多 | | hook 系統 | 1\. 不需要實現大量接口方法 2. 由于最終還是交給系統去處理,各種處理相對比較完整 | 1\. 需要適配不同的系統及設備 2. 對開發者要求比較高,需要對系統實現有深入的了解 | #### hook系統(Instrumentation) ![](https://img.kancloud.cn/a9/62/a96261c2e568d197863ae56fbfab82c3_640x240.png) 有兩個關鍵點,execStartActivity?和?newActivity。 execStartActivity?是在啟動 Activity 的時候必經的一個過程,這時還沒有到達 AMS,所以,在這里把 Activity 替換成宿主中已經注冊的?StubActivity,這樣 AMS 在檢測 Activity 的時候就認為已經注冊過了。newActivity?是創建 Activity 實例,這里要返回真正需要運行的插件 Activity,這樣后面系統就會基于這個 Activity 實例來進行對應的生命周期的調用。 資源 ## shadow實現 ### Manager VS Loader VS Container Manager的功能就是管理插件,包括插件的下載邏輯、入口邏輯,預加載邏輯等.反正就是一切還沒有進入到Loader之前的所有事情。 Loader就是負責加載插件Activity,然后實現插件Activity的生命周期等功能的那部分核心邏輯了。 Container就是那些注冊在宿主AndroidManifest中的代理殼子。由于Activity的創建是系統根據Activity的名字直接通過宿主的PathClassLoader構造的,所以這些Activity必須打包在宿主中才能處于PathClassLoader,才能被系統找到。所以Container是不能放到Loader中,通過動態加載的一般方法加載的。因為前面提到的一般方法都是要new一個新的ClassLoader加載動態實現的。 ### ClassLoader 我們可以通過修改ClassLoader的parent,為ClassLoader新增一個parent。將原本的 ~~~ BootClassLoader <- PathClassLoader ~~~ 結構變為 ~~~ BootClassLoader <- DexClassLoader <- PathClassLoader ~~~ ,插入的DexClassLoader加載了ContainerActivity就可以使得系統在向PathClassLoader查找ContainerActivity時能夠正確找到實現。 ### Activity 核心:加入的ShadowActivity就是這個中間層。通過這個中間層讓Android系統看不到插件,也讓插件看不到Android系統。 技術:字節碼插樁 # 參考資料 [Shadow源碼解析](https://github.com/ChenSiLiang/android-toy/blob/master/Shadow%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%E7%AC%94%E8%AE%B0/Shadow%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90.md) [Android 插件化的今生前世大揭秘](https://mp.weixin.qq.com/s/EuCqudpPnBRidtmZBocNYg)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看