中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android動態加載字節碼

發布時間:2020-07-14 14:09:40 來源:網絡 閱讀:421 作者:大水牛牛 欄目:移動開發

概述

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

Android系統加載字節碼

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

實例講解

×××,需要準備兩個工程,一個Android工程(AndroidPractice),Android工程中去加載字節碼。寧外一個普通的java工程(DexModule),下面看看工程結構。需要注意的是IDynamicLoad這個接口在兩個工程中都需要,且包名一致。

Android動態加載字節碼

字節碼加載工程結構

DexModule工程講解

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

 

package com.vjson.module;

public interface IDynamicLoad {
    public String dexLoad();
}
<span >package com.vjson.module;

public class DynamicLoad implements IDynamicLoad {
    @Override
    public String dexLoad() {
        return "dexload practice";
    }
}</span>


導出jar包

在導出jar包的時候一定要注意,不要導出IDynamicLoad這個接口文件,因為Android工程中已經有一個接口文件,不然加載字節碼的時候會導致字節碼沖突。

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包的完整性驗證和安全性驗證。 


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新和县| 肥东县| 新源县| 惠州市| 盐津县| 海晏县| 玉树县| 涞源县| 木里| 灵武市| 金阳县| 禄丰县| 车致| 鲜城| 白玉县| 东乡县| 阿克| 揭东县| 镶黄旗| 若羌县| 扶绥县| 班玛县| 衢州市| 博白县| 肃宁县| 天台县| 姜堰市| 会理县| 延长县| 新源县| 苗栗市| 阿巴嘎旗| 华容县| 蓬安县| 通渭县| 靖边县| 吴桥县| 太仆寺旗| 武邑县| 泾川县| 凌海市|