Android外掛化(二):使用DexClassLoader動態載入assets中的apk
轉自:http://blog.csdn.net/nupt123456789/article/details/50411581
簡介
上一篇部落格講到,我們可以使用MultiDex.java載入離線的apk檔案。需要注意的是,apk中的類是載入到當前的PathClassLoader當中的,如果apk檔案過多,可能會出現ANR的情況。那麼,我們能不能使用DexClassLoader載入apk呢?當然是可以的!首先看一下Doc文件.
<code class="language-html hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">A class loader that loads classes from .jar and .apk files containing a classes.dex entry. This can be used to execute code not installed as part of an application.</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
也就是說,DexClassLoader可以載入一個含有classes.dex檔案的壓縮包,既可以是jar也可以是apk。那麼載入一個離線的apk檔案需要注意哪些呢?
-
1.DexClassLoader的構造方法:
DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent) -
2.私有目錄
This class loader requires an application-private, writable directory to cache optimized classes.
瞭解到上述兩點,我們就可以根據DexClassLoader所需要的引數,動態載入assets中的apk了。
原始碼
BundleClassLoaderManager
該類主要是負責管理這些DexClassLoader的,首先,我們定義了一個叫做BundleDexClassLoader的類,它繼承自DexClassLoader,用於載入離線的apk檔案。每一個apk檔案對應一個BundleDexClassLoader,而BundleClassLoaderManager則儲存了一個List,在載入的時候,用於查詢類。具體程式碼如下:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> net.mobctrl.hostapk; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.io.File; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.io.FilenameFilter; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.util.ArrayList; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.util.List; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.annotation.TargetApi; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.content.Context; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> android.os.Build; <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @Author</span> Zheng Haibo *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @PersonalWebsite</span> http://www.mobctrl.net *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @version</span> $Id: BundleClassLoaderManager.java, v 0.1 2015年12月11日 下午7:30:59 * mochuan.zhb Exp $ *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @Description</span> */</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@TargetApi</span>(Build.VERSION_CODES.ICE_CREAM_SANDWICH) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">BundleClassLoaderManager</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> List<BundleDexClassLoader> bundleDexClassLoaderList = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ArrayList<BundleDexClassLoader>(); <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 載入Assets裡的apk檔案 *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> context */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">install</span>(Context context) { AssetsManager.copyAllAssetsApk(context); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 獲取dex檔案列表</span> File dexDir = context.getDir(AssetsManager.APK_DIR, Context.MODE_PRIVATE); File[] szFiles = dexDir.listFiles(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> FilenameFilter() { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">accept</span>(File dir, String filename) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> filename.endsWith(AssetsManager.FILE_FILTER); } }); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (File f : szFiles) { System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"debug:load file:"</span> + f.getName()); BundleDexClassLoader bundleDexClassLoader = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> BundleDexClassLoader( f.getAbsolutePath(), dexDir.getAbsolutePath(), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, context.getClassLoader()); bundleDexClassLoaderList.add(bundleDexClassLoader); } } <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * 查詢類 * *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> className *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @return</span> *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @throws</span> ClassNotFoundException */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> Class<?> <span class="hljs-title" style="box-sizing: border-box;">loadClass</span>(Context context,String className) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> ClassNotFoundException { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { Class<?> clazz = context.getClassLoader().loadClass(className); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (clazz != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"debug: class find in main classLoader"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> clazz; } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) { e.printStackTrace(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (BundleDexClassLoader bundleDexClassLoader : bundleDexClassLoaderList) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { Class<?> clazz = bundleDexClassLoader.loadClass(className); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (clazz != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"debug: class find in bundle classLoader"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> clazz; } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) { e.printStackTrace(); } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ClassCastException(className + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" not found exception"</span>); } } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li></ul>
注意點:
-
1.install方法
install方法主要是將assets中的apk全部拷貝到私有目錄,然後再遍歷私有目錄,使用BundleDexClassLoader載入apk檔案,然後將這些BundleDexClassLoader儲存到陣列中。 -
2.loadClass方法
該方法先從當前的ClassLoader中查詢需要的類,如果找不到,在從List中遍歷查詢。
DEMO執行
在MainActivity中,我們可以通過如下方式,呼叫apk類中的方法:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">loadApk</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> { Class<?> clazz = BundleClassLoaderManager.loadClass(getApplicationContext(), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"net.mobctrl.normal.apk.Utils"</span>); Constructor<?> constructor = clazz.getConstructor(); Object bundleUtils = constructor.newInstance(); Method printSumMethod = clazz.getMethod(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"printSum"</span>, Context.class, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>.class, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>.class, String.class); printSumMethod.setAccessible(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>); Integer sum = (Integer) printSumMethod.invoke(bundleUtils, getApplicationContext(), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"計算結果"</span>); System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"debug:sum = "</span> + sum); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (ClassNotFoundException e) { e.printStackTrace(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (SecurityException e) { e.printStackTrace(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (NoSuchMethodException e) { e.printStackTrace(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IllegalArgumentException e) { e.printStackTrace(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (InstantiationException e) { e.printStackTrace(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (IllegalAccessException e) { e.printStackTrace(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (InvocationTargetException e) { e.printStackTrace(); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul>
與MultiDex不同時,我們是通過BundleClassLoaderManager來載入類的,而不是當前的ClassLoader。
改進方案
正如BundleClassLoaderManager中的loadClass方法,其實我們建立一個ClassLoader物件,通過重寫當前ClassLoader的findClass方法即可,然後在Override的findClass方法中,首先從當前ClassLoader中查詢類,然後再從BundleDexClassLoader中遍歷查詢,這樣既可以在Host專案中呼叫Bundle中的類,也能夠在Bundle中呼叫Host中的類。
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"> mClassLoader = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ClassLoader(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.getClassLoader()) { <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> Class<?> <span class="hljs-title" style="box-sizing: border-box;">findClass</span>(String className) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> ClassNotFoundException { Class clazz = BundleClassLoaderManager.loadClass(context,className); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (clazz == <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throw</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ClassNotFoundException(className); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> clazz; } }; </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>
總結
上一篇部落格和這一篇部落格將的都是類的載入。如果所需要載入的類都是工具類,不需要載入資源等,那麼上面的方案都沒啥問題。但是如果載入的類是Fragment或者Activity等UI,需要引用資原始檔,這又改如何處理呢?
下一篇博文:Android資源的離線載入。
參考
1.BaseDexClassLoader原始碼
相關文章
- Android外掛化(一):使用改進的MultiDex動態載入assets中的apkAndroidIDEAPK
- Android外掛化(三):載入外掛apk中的Resource資源AndroidAPK
- 外掛化知識梳理(7) 類的動態載入入門
- Android 外掛化 動態升級Android
- 動態載入APK原理分享APK
- APK動態載入框架(DL)解析APK框架
- 外掛化知識梳理(8) 類的動態載入原始碼分析原始碼
- 寫個js/css動態載入的JavaScript外掛JSCSSJavaScript
- Android-動態載入外掛資源,皮膚包的實現原理Android
- 使用 Webapck 優化 VS Code 外掛載入效能Web優化
- 外掛化知識梳理(9) 資源的動態載入示例及原始碼分析原始碼
- Spring Boot 如何熱載入 jar 實現動態外掛?Spring BootJAR
- Spring Boot 如何熱載入jar實現動態外掛?Spring BootJAR
- Activity的外掛化(二)
- framework外掛化技術-類載入Framework
- Android外掛化原理(一)Activity外掛化Android
- Android外掛化技術之旅 1 開篇 - 實現啟動外掛與呼叫外掛中的Activity和ServiceAndroid
- 熱修復與外掛化基礎——Java與Android的類載入器JavaAndroid
- Android動態載入jar/dexAndroidJAR
- 基於 webpack 的 SPA 單頁 Web 應用 動態載入外掛的機制Web
- Flutter外掛開發之APK自動安裝FlutterAPK
- 外掛化設計二
- 圖片載入外掛imagesLoaded的配置和使用
- 動態庫so打包到android apkAndroidAPK
- aspnetcore外掛開發dll熱載入 二NetCore
- Android Studio Plugin 外掛開發教程(二) —— 外掛SDK中的常用物件介紹AndroidPlugin物件
- 使用dlopen載入動態庫
- Android外掛化的相容性(中):Android P的適配Android
- android: 動態載入碎片佈局的技巧Android
- Pro Motion Blur Mac(動態模外掛fcpx外掛)Mac
- 位元組碼技術---------動態代理,lombok外掛底層原理。類載入器Lombok
- 外掛化之程式碼呼叫與載入資源
- Android外掛化開篇Android
- 淺析Android外掛化Android
- Android 開發中如何動態載入 so 庫檔案Android
- Android外掛化的一種方案Android
- Android外掛化——VirtualAPK外掛框架接入專案AndroidAPK框架
- web的自動化測試外掛Selenium-IDE外掛的安裝使用WebIDE