Android動(dòng)態(tài)加載dex技術(shù)初步了解

1.概述

  • 1.1 Android使用Dalvik虛擬機(jī)加載可執(zhí)行程序,所以不能直接加載基于class的jar,而是需要將class轉(zhuǎn)化為dex字節(jié)碼,從而執(zhí)行代碼。優(yōu)化后的字節(jié)碼文件可以存在一個(gè).jar中,只要其內(nèi)部存放的是.dex即可使用,這里我們直接使用AS工程
    直接打包出APK然后解壓去除dex文件即可

  • 1.2 Android支持動(dòng)態(tài)加載的兩種方式是:DexClassLoader和PathClassLoader,DexClassLoader可加載jar/apk/dex,且支持從SD卡加載;PathClassLoader只支持加載已經(jīng)安裝到 Android 系統(tǒng)中的 apk 文件

  • 1.3 接下來(lái)我們使用DexClassLoader實(shí)現(xiàn)加載sd卡的dex文件并且調(diào)用內(nèi)部的方法

2.實(shí)踐

  • 2.1 首先我們定義個(gè)IShowToast接口,這個(gè)其實(shí)要不要都可以
public interface IShowToast {

  public int showToast(android.app.Application context);
}

  • 2.2 在定義實(shí)踐類
public class ShowToastImpl implements IShowToast {

  @Override
  public int showToast(android.app.Application context) {
    Toast.makeText(context, "我來(lái)自另一個(gè)dex文件", Toast.LENGTH_LONG).show();
    return 100;
  }

  public void test() {
    Log.e("\"我來(lái)自另一個(gè)dex文件\"","我來(lái)自另一個(gè)dex文件");
  }
}


  • 2.3 跑當(dāng)前的Android工程生成dex文件,將生成的dex文件拷貝到sd卡下
  • 2.4 另開(kāi)啟一個(gè)新工程測(cè)試代碼如下
public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    try {
      File dexOutputDir = getDir("dex1", 0);
      String dexPath = Environment.getExternalStorageDirectory().toString() + File.separator + "a";
      File file = new File(dexPath);
      Log.e("MainActivity",file.length()+"");
      DexClassLoader loader = new DexClassLoader(dexPath,
          dexOutputDir.getAbsolutePath(),
          null, getClassLoader());
      Class clz = loader.loadClass("com.Company.Demo.ShowToastImpl");
      Method m1 = clz.getDeclaredMethod("test");
      Method showToast = clz
          .getDeclaredMethod("showToast", new Class[]{getApplication().getClass()});
      m1.invoke(clz.newInstance());
      showToast.invoke(clz.newInstance(),getApplication());
    } catch (Exception e) {
      Log.e("MainActivity", "error happened", e);
    }
  }
}



其實(shí)這里就是通過(guò)DexClassLoader得到sd卡的dex的ShowToastImpl對(duì)象然后通過(guò)反射即可調(diào)用器內(nèi)部的方法

此處需要注意DexClassLoader的四個(gè)參數(shù):
參數(shù)1 dexPath:待加載的dex文件路徑,如果是外存路徑,一定要加上讀外存文件的權(quán)限(<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> ),否則會(huì)報(bào)與上面一樣的錯(cuò)誤,這點(diǎn)參考文章2中說(shuō)這個(gè)權(quán)限可有可無(wú)是錯(cuò)誤的。(更正下:Android4.4 KitKat及以后的版本需要此權(quán)限,之前的版本不需要權(quán)限)

           參數(shù)2 optimizedDirectory:解壓后的dex存放位置,此位置一定要是可讀寫且僅該應(yīng)用可讀寫(安全性考慮),所以只能放在data/data下。本文getDir("dex1", 0)會(huì)在/data/data/**package/下創(chuàng)建一個(gè)名叫”app_dex1“的文件夾,其內(nèi)存放的文件是自動(dòng)生成a.dex;如果不滿足條件,Android會(huì)報(bào)的錯(cuò)誤為:

          java.lang.IllegalArgumentException: optimizedDirectory not readable/writable: /storage/sdcard0

          java.lang.IllegalArgumentException: Optimized data directory /storage/sdcard0 is not owned by the current user. Shared storage cannot protect your application from code injection attacks.

           參數(shù)3 libraryPath:指向包含本地庫(kù)(so)的文件夾路徑,可以設(shè)為null

           參數(shù)4 parent:父級(jí)類加載器,一般可以通過(guò)Context.getClassLoader獲取到,也可以通過(guò)ClassLoader.getSystemClassLoader()取到。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,007評(píng)論 25 709
  • Android插件化基礎(chǔ)的主要內(nèi)容包括 Android插件化基礎(chǔ)1-----加載SD上APKAndroid插件化基...
    隔壁老李頭閱讀 5,544評(píng)論 5 36
  • 動(dòng)態(tài)加載技術(shù) 介紹 在程序運(yùn)行的時(shí)候,加載一些程序自身原本不存在的可執(zhí)行文件并運(yùn)行這些文件里的代碼邏輯。 動(dòng)態(tài)調(diào)用...
    冰點(diǎn)k閱讀 4,207評(píng)論 1 11
  • 上篇文章講到了apk的分包,通過(guò)multidex構(gòu)建出包含多個(gè)dex文件的apk,從而解決65536的方法數(shù)限制問(wèn)...
    the_q閱讀 8,295評(píng)論 1 15
  • 民以食為天,食以安為先,這是近幾年大家常掛在嘴邊的話,但是,現(xiàn)在不光要吃的安全,還要吃的營(yíng)養(yǎng)健康,這就需要不斷提高...
    傲梅寒雪閱讀 825評(píng)論 0 2

友情鏈接更多精彩內(nèi)容