關於Android 動態載入 jar 檔案

來源:互聯網
上載者:User

標籤:android   package   public   java   虛擬機器   

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.


650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/5B/84/wKiom1UKkMrQb82RAACcD1kPgqo464.jpg" title="QQ20150319170138.png" alt="wKiom1UKkMrQb82RAACcD1kPgqo464.jpg" />

程式碼:


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 , 表明動態載入成功。


 


本文出自 “Lua學習筆記” 部落格,請務必保留此出處http://mythwind.blog.51cto.com/6506705/1622297

關於Android 動態載入 jar 檔案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.