Android动态加载类

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

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

dx --dex --no-strict --output <输出dex路径> 

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+++++++++++++++++++++++++++++++++");
    }
}

 

你可能感兴趣的:(android系统相关)