Android動態加載類

1.把class文件打包成dex文件。

在android-sdk/build-tool下有個dx腳本工具,可以將class文件打包成dex文件。

dx --dex --no-strict --output <輸出dex路徑> <class文件路徑>

2.將dex文件放入手機中的某個路徑下。

3.使用DexClassLoader加載dex文件中的類。

Activity代碼:

package com.champion.loaddexdemo;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import junit.framework.Assert;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import dalvik.system.DexClassLoader;

public class MainActivity extends AppCompatActivity {
    int storageRequestCode = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(PackageManager.PERMISSION_DENIED == checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)){
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, storageRequestCode);
        }
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //本例中是將out.dex放在sdcard根目錄下
                File dexFile = new File(Environment.getExternalStorageDirectory(), "out.dex");
                if(!dexFile.exists()){
                    System.out.println("dexFile not exists");
                    return;
                }
                File odexDir = getDir("odex", Context.MODE_PRIVATE);
                if(!odexDir.exists()){
                    System.out.println("odexDir not exists");
                    odexDir.mkdir();
                }
                //新建一個DexClassLoader,以dex文件的路徑爲參數,傳入一個放置odex文件的文件夾路徑
                DexClassLoader dexClassLoader = new DexClassLoader(dexFile.getAbsolutePath(),
                        odexDir.getAbsolutePath(), null, getClassLoader());
                try {
                    //使用dexClassLoader進行加載dex文件中的類
                    Class clazz = dexClassLoader.loadClass("com.champion.loaddexdemo.dynanmicLoadedTest");
                    Object object = clazz.newInstance();
                    //調用類中的方法
                    Method method = clazz.getMethod("load");
                    method.invoke(object);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode == storageRequestCode){
            System.out.println("request code success!!!!!");
        }
    }

}

被加載的測試類代碼:

package com.champion.loaddexdemo;

public class dynanmicLoadedTest {
    static {
        System.out.println("static load success!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    }
    public void load(){
        System.out.println("load+++++++++++++++++++++++++++++++++");
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章