Android中的DexClassLoader使用

1.Java和Android中的类加载器的区别

Java:ClassLoader
Android:DexClassLoader

2.DexClassLoader使用

实例:应用程序MyHost调用应用程序MyPlugin中PluginClass类中的方法invoke()
步骤:

1)创建MyPlugin应用程序:按正常的创建应用的步骤创建应用程序MyPlugin

2)在MyPlugin中创建PluginClass类:如下代码(去除import)

public class PluginClass {
private static final String tag = PluginClass.class.getSimpleName();


public PluginClass() {
Log.i(tag, "initialized");
}


public void invoke(String s) {
Log.i(tag, s);
}
}

3)将MyPlugin应用程序运行在Android设备上

4)创建MyHost应用程序:按正常的创建应用的步骤创建应用程序MyHost

5)在MyHost中创建MyHost类

public class MyHost {
private static final String tag = MyHost.class.getSimpleName();
private Context mContext = null;

public MyHost(Context context) {
this.mContext = context;
}

public String useDexClassLoader() {
String result = null;
Intent intent = new Intent();
intent.setPackage("com.mokee.myplugin");
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> plugins = pm.queryIntentActivities(intent, 0);
if(plugins.size() <= 0) {
Log.i(tag, "Resolve Info List size is :" + plugins.size());
return null;
}

ResolveInfo resolveInfo = plugins.get(0);
ActivityInfo activityInfo = resolveInfo.activityInfo;

String div = System.getProperty("path.separator");  
        String packageName = activityInfo.packageName;  
        String dexPath = activityInfo.applicationInfo.sourceDir;  
        //目标类所在的apk或者jar的路径,class loader会通过这个路径来加载目标类文件  
        String dexOutputDir = mContext.getApplicationInfo().dataDir;  
        //由于dex文件是包含在apk或者jar文件中的,所以在加载class之前就需要先将dex文件解压出来,dexOutputDir为解压路径  
        String libPath = activityInfo.applicationInfo.nativeLibraryDir;  
        //目标类可能使用的c或者c++的库文件的存放路径  
          
        result = "div:" + div + "   " +   
                "packageName:" + packageName + "   " +  
                "dexPath:" + dexPath + "   " +  
                "dexOutputDir:" + dexOutputDir + "   " +  
                "libPath:" + libPath;
        Log.i(tag, result);  
        
        DexClassLoader dcLoader = new DexClassLoader(dexPath, dexOutputDir, libPath, this.getClass().getClassLoader());
        try {
Class<?> clazz = dcLoader.loadClass(packageName + ".PluginClass");
Object obj = clazz.newInstance();
Class[] param = new Class[1];  
            param[0] = String.class;  
            Method action = clazz.getMethod("invoke", param);  
            action.invoke(obj, "Test this function");  
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
        return result;
}
}

6)在MyHost应用程序的MainActivity中初始化MyHost类,并调用useDexClassLoader方法,同时接受返回值,将返回值显示在TextView控件上。代码如下:

public class MainActivity extends Activity {
private TextView show;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

show = (TextView) findViewById(R.id.show);

MyHost host = new MyHost(this);
String hostResult = host.useDexClassLoader();

show.setText(hostResult);
}
}

7)将MyHost应用程序安装在Android设备上,即可通过Log看出其调用MyPlugin应用程序的invoke方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值