Android動態載入位元組碼

來源:互聯網
上載者:User

標籤:

概述

面對App商務邏輯的頻繁變更,如果每一次改變都對App進行一次升級,會降低App的使用者體驗,那麼App進行模組化升級(這裡與增量升級是不同的)是很好的解決方案,讓使用者在完全無感覺的情況下改變App中的商務邏輯。要實現這種模組化升級,動態載入位元組碼(jar/dex)就是實現這個需求的理論基礎。

Android系統載入位元組碼

Android的虛擬機器(Dalvik VM)無法識別普通jar包中的位元組碼,所以需要通過位元組碼轉換工具將jar轉換成dex,jar包中的所有位元組碼都會打進classes.dex,這樣的位元組碼才能被Dalvik虛擬機器識別。

執行個體講解

源碼下載,需要準備兩個工程,一個Android工程(AndroidPractice),Android工程中去載入位元組碼。寧外一個普通的java工程(DexModule),下面看看工程結構。需要注意的是IDynamicLoad這個介面在兩個工程中都需要,且包名一致。

位元組碼載入工程結構

DexModule工程講解

DexModule這個工程中只有兩個類,一個是介面IDynamicLoad,這個介面就是文章開始提到的模組升級的關鍵,只需要提前約定好介面,將介面發布給調用方,具體的實現對調用方完全是透明的,這樣就能做到隨意的更改介面的實現,寧一個是該介面的實作類別DynamicLoad。實現非常簡單就是返回一個字串。

 

package com.vjson.module;public interface IDynamicLoad {    public String dexLoad();}
<span style="font-weight: normal;">package com.vjson.module;public class DynamicLoad implements IDynamicLoad {    @Override    public String dexLoad() {        return "dexload practice";    }}</span>

 

匯出jar包

在匯出jar包的時候一定要注意,不要匯出IDynamicLoad這個介面檔案,因為Android工程中已經有一個介面檔案,不然載入位元組碼的時候會導致位元組碼衝突。

匯出jar包

 

位元組碼轉換

用前面提到的位元組碼轉換工具,將jar轉換為Dalvik VM認識的dex。d2j-jar2dex.sh這個命令的-o參數指定輸出檔案。

 

d2j-jar2dex.sh -o module.jar dynamicLoad.jar

 

然後將產生的module.jar放到手機的sdcard裡面。

 

adb push module.jar /mnt/sdcard/

 

載入dex

載入位元組碼需要用到DexClassLoader這個類,它負責從jar包中提取(解壓縮的一個過程)classes.dex,並且將位元組碼載入到記憶體,接下來就通過loadClass方法載入需要的類,看下面的詳細代碼,注意高亮的行。

 

package com.vjson.practice;import java.io.File;import android.annotation.TargetApi;import android.app.Activity;import android.os.Build;import android.os.Bundle;import android.os.Environment;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;import com.vjson.dynamicload.R;import com.vjson.module.IDynamicLoad;import dalvik.system.DexClassLoader;public class MainActivity extends Activity {    private Button mBtn;    private IDynamicLoad mDynamicLoad;    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)    public static final IDynamicLoad loadByteCode() {        File jarFile = new File(Environment.getExternalStorageDirectory().toString() + File.separator + "module.jar");        File optmizedPath = BaseApplication.sInstance.getDir("dex", MODE_PRIVATE);        DexClassLoader loader = new DexClassLoader(jarFile.getAbsolutePath(),                optmizedPath.getAbsolutePath(), null,                BaseApplication.sInstance.getClassLoader());        IDynamicLoad dynaicLoad = null;        try {            Class<?> clazz = loader.loadClass("com.vjson.module.DynamicLoad");            dynaicLoad = (IDynamicLoad) clazz.newInstance();        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }        return dynaicLoad;    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mDynamicLoad = loadByteCode();        mBtn = (Button) findViewById(R.id.btn);        mBtn.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                String str = mDynamicLoad.dexLoad();                Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();            }        });    }}

 

注意代碼的26行,通過context的getDir(“dex”, MODE_PRIVATE)方法擷取應用程式的私人目錄,這是由於從Android4.1.2開始由於安全原因,防止代碼注入攻擊,必須將位元組碼放到私人目錄下面也就是data/data/應用程式套件組合名/。從jar包中提前出來的classes.dex就放在這個目錄下面。

總結

本文主要介紹了,Android中的位元組碼載入技術,為接下來的文章Android模組化升級提供一個理論基礎,其實最精髓的地方就是定義介面,通過介面調用端和實現端進行通訊。在模組化升級中將會講解jar包的完整性驗證和安全性驗證。 

Android動態載入位元組碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.