Android退出apk函数,Android DexClassLoader调用其他apk中的函数

场景:

手机内安装两个应用A和B,B通过DexClassLoader调用A中的方法

原理:

1.通过Intent查询系统注册的A应用的Activity信息

2.从得到的Activity信息中得到A应用的包名,apk或jar存放路径等信息

3.通过得到A应用的信息构造DexClassLoader对象

4.得到的DexClassLoader对象是和应用A关联起来的,然后去通过DexClassLoader对象加载你需要使用的类。

5.通过反射调用A应用的里面的方法。

A应用实现:

创A工程,包名为com.cn.plugin,在com.cn.plugin目录下创建一个类

package com.cn.plugin;

import android.util.Log;

public class PluginClass {

public PluginClass() {

Log.i("Plugin", "PluginClass client initialized");

}

public int function1(int a, int b) {

return a + b;

}

}

然后给A的一个Activity配置一个Action,这里直接个MainActivty设置一个Action

给应用A的MainActivity指定了一个Action为”com.cn.plugin.client”至此,应用A的工作做完了,安装应用A。

新建工程B,在B中调用下面函数

public void useDexClassLoader() {

Intent intent = new Intent("com.cn.plugin.client", null);

PackageManager pm = getPackageManager();

//通过Intent查询ResolveInfo

final List plugins = pm.queryIntentActivities(intent, 0);

//取出第一个ResolveInfo,因为这只是一个Demo,所以直接取第一个就是我们所要的A中MainActivity信息

ResolveInfo rInfo = plugins.get(0);

//得到A应用的Activity信息

ActivityInfo aInfo = rInfo.activityInfo;

//通过ActivityInfo得到构造DexClassLoader对象的参数信息

String packageName = aInfo.packageName;

String dexPath = aInfo.applicationInfo.sourceDir;

String dexOutputDir = getApplicationInfo().dataDir;

String libPath = aInfo.applicationInfo.nativeLibraryDir;

Log.d("TAG", "packageName is : " + packageName + "\n" + "dexPath is : "

+ dexPath + "\ndexOutputDir is : " + dexOutputDir

+ "\nlibPath is : " + libPath);

//构造ClassLoader对象

DexClassLoader classLoader = new DexClassLoader(dexPath, dexOutputDir,

libPath, getClass().getClassLoader());

try {

//通过全路径名加载PluginClass类

Class> clazz = classLoader

.loadClass(packageName + ".PluginClass");

//构造PluginClass对象

Object obj = clazz.newInstance();

Class>[] params = new Class[2];

params[0] = Integer.TYPE;

params[1] = Integer.TYPE;

//反射调用function1方法

Method action = clazz.getMethod("function1", params);

Integer ret = (Integer) action.invoke(obj, 12, 34);

Log.i("Host", "return value is " + ret);

} catch (ClassNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InstantiationException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IllegalAccessException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchMethodException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IllegalArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvocationTargetException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

安装B应用,在调用的地方查看打印如下:

12-30 23:53:08.077: D/TAG(19891): packageName is : com.cn.plugin

12-30 23:53:08.077: D/TAG(19891): dexPath is : /data/app/com.cn.plugin-1/base.apk

12-30 23:53:08.077: D/TAG(19891): dexOutputDir is : /data/user/0/com.cn.host

12-30 23:53:08.077: D/TAG(19891): libPath is : /data/app/com.cn.plugin-1/lib/arm64

12-30 23:53:08.083: W/System(19891): ClassLoader referenced unknown path: /data/app/com.cn.plugin-1/lib/arm64

12-30 23:53:08.084: I/Plugin(19891): PluginClass client initialized

12-30 23:53:08.084: I/Host(19891): return value is 46

成功的通过B应用调用A应用的方法完成了两个数的相加。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值