您好,登錄后才能下訂單哦!
Android 中怎么動態加載 jar 文件,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
1.1 首先需要了解一點:在Android中可以動態加載,但無法像Java中那樣方便動態加載jar
原因:Android的虛擬機(Dalvik VM)是不認識Java打出jar的byte code,需要通過dx工具來優化轉換成Dalvik byte code才行。這一點在咱們Android項目打包的apk中可以看出:引入其他Jar的內容都被打包進了classes.dex。
所以這條路不通,請大家注意。
1.2 當前哪些API可用于動態加載
1.2.1 DexClassLoader
這個可以加載jar/apk/dex,也可以從SD卡中加載,也是本文的重點。
1.2.2 PathClassLoader
只能加載已經安裝到Android系統中的apk文件。
1.3 代碼
package com.example.dynamicloaddemo.jar; public class DynamicTest implements IDynamic { @Override public String helloWorld() { return "Hello World Form JAR"; } }
將這個類導出,注意,編譯的時候必須是 java 1.6 編譯(java 1.7 編譯會出現錯誤:Zip is good, but no classes.dex inside, and no valid .odex file in the same directory)
1.4 編譯文件之后將上面的類打包為 dynamic.jar
1.4.1 下載jar 轉化 dex 工具,將打包好的jar拷貝到SDK安裝目錄android-sdk-windows\platform-tools下,DOS進入這個目錄,執行命名: dx --dex --output=test.jar dynamic.jar
1.4.2 將test.jar拷貝到 /data/data/packagename/app-libs/
放在 SDCard 上會出現錯誤 Optimized data directory /data/data/com.example.dynamicloaddemo/files/test.jar is not owned by the current user. Shared storage cannot protect your application from code injection attacks.
程序代碼:
public class MainActivity extends Activity { Button mToastButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mToastButton = (Button) findViewById(R.id.main_btn); // Before the secondary dex file can be processed by the DexClassLoader, // it has to be first copied from asset resource to a storage location. // final File dexInternalStoragePath = new File(getDir("dex", // Context.MODE_PRIVATE),SECONDARY_DEX_NAME); // if (!dexInternalStoragePath.exists()) { // mProgressDialog = ProgressDialog.show(this, // getResources().getString(R.string.diag_title), // getResources().getString(R.string.diag_message), true, false); // // Perform the file copying in an AsyncTask. // // 從網絡下載需要的dex文件 // (new PrepareDexTask()).execute(dexInternalStoragePath); // } else { // mToastButton.setEnabled(true); // } System.out.println(getDir("libs", Context.MODE_PRIVATE)); System.out.println(getFilesDir()); System.out.println(getCacheDir()); System.out.println(getDir("libs", Context.MODE_PRIVATE)); System.out.println(getDir("libs", Context.MODE_PRIVATE)); mToastButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { // Internal storage where the DexClassLoader writes the // optimized dex file to. // final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE); final File optimizedDexOutputPath = new File(getDir("libs", Context.MODE_PRIVATE) + File.separator + "test.jar"); // Initialize the class loader with the secondary dex file. // DexClassLoader cl = new // DexClassLoader(dexInternalStoragePath.getAbsolutePath(), // optimizedDexOutputPath.getAbsolutePath(), // null, // getClassLoader()); /* DexClassLoader cl = new DexClassLoader(optimizedDexOutputPath.getAbsolutePath(), Environment .getExternalStorageDirectory().toString(), null, getClassLoader()); */ DexClassLoader cl = new DexClassLoader(optimizedDexOutputPath.getAbsolutePath(), getDir("libs", Context.MODE_PRIVATE).getAbsolutePath(), null, getClassLoader()); Class<?> libProviderClazz = null; try { // Load the library class from the class loader. // 載入從網絡上下載的類 // libProviderClazz = // cl.loadClass("com.example.dex.lib.LibraryProvider"); libProviderClazz = cl.loadClass("com.example.dynamicloaddemo.jar.DynamicTest"); // Cast the return object to the library interface so that // the // caller can directly invoke methods in the interface. // Alternatively, the caller can invoke methods through // reflection, // which is more verbose and slow. // LibraryInterface lib = (LibraryInterface) // libProviderClazz.newInstance(); IDynamic lib = (IDynamic) libProviderClazz.newInstance(); // Display the toast! // lib.showAwesomeToast(view.getContext(), "hello 世界!"); Toast.makeText(MainActivity.this, lib.helloWorld(), Toast.LENGTH_SHORT).show(); } catch (Exception exception) { // Handle exception gracefully here. exception.printStackTrace(); } } }); } }
1.5 運行,出現 Hello World From JAR , 表明動態加載成功。
看完上述內容,你們掌握Android 中怎么動態加載 jar 文件的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。