Android中apk文件里的dex文件是对java编译出来的.class文件进行重新打包,当然在打包之前会利用自己的协议做一些数据处理,例如优化函数表和变量表。在java程序中是使用classloader来加载这些编译生成的.class文件,然而在android程序中是通过DexClassLoader来装载这些文件的.这里我们就可以通过DexClassLoader在程序A里面动态装载程序B中的类,并且来调用B程序中的方法.


1.首先先建立一个普通的Android工程,在这个工程中定义一个叫做plugin的类,类中实现一个简单的方法,如下所示:

<span style="font-size:14px;">public class PluginClass {private static String TAG = PluginClass.class.getSimpleName();public PluginClass(){Log.i(TAG, "initialized");}public void invoke(String s){Log.i(TAG, s);}}</span>
2.将这个Android工程运行到安卓设备当中去

3.再重新建立一个Android工程,其中定义一个叫做host的类,在这个类中实现DexClassLoader动态加载第一个工程中的plugin类,如下所示:

<span style="font-size:14px;">public class HostClass {private static String TAG = HostClass.class.getSimpleName();private Context mContext = null;public HostClass(Context contect){mContext = contect;}public void useDexClassLoader(){Intent intent = new Intent();intent.setPackage("com.example.plugin");PackageManager pm = mContext.getPackageManager();final List<ResolveInfo> plugins = pm.queryIntentActivities(intent,0);if(plugins.size() <= 0){Log.i(TAG, "resolve info size is:" + plugins.size());return;}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++的库文件的存放路径Log.i(TAG, "div:" + div + "   " + "packageName:" + packageName + "   " +"dexPath:" + dexPath + "   " +"dexOutputDir:" + dexOutputDir + "   " +"libPath:" + libPath);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) {Log.i(TAG, "ClassNotFoundException");} catch (InstantiationException e) {Log.i(TAG, "InstantiationException");} catch (IllegalAccessException e) {Log.i(TAG, "IllegalAccessException");} catch (NoSuchMethodException e) {Log.i(TAG, "NoSuchMethodException");} catch (IllegalArgumentException e) {Log.i(TAG, "IllegalArgumentException");} catch (InvocationTargetException e) {Log.i(TAG, "InvocationTargetException");}}}</span>
4.运行第二个工程之后查看log就会发现host通过DexClassLoader加载了pluginclass类,并成功调用了plugin中的方法
<span style="font-size:14px;">I/HostClass( 8341): div::   packageName:com.example.plugin   dexPath:/data/app/com.example.plugin-1.apk   dexOutputDir:/data/data/com.example.host   libPath:/data/app-lib/com.example.plugin-1D/dalvikvm( 8341): DexOpt: --- BEGIN 'com.example.plugin-1.apk' (bootstrap=0) ---D/dalvikvm( 8341): DexOpt: --- END 'com.example.plugin-1.apk' (success) ---D/dalvikvm( 8341): DEX prep '/data/app/com.example.plugin-1.apk': unzip in 39ms, rewrite 723msI/PluginClass( 8341): initializedI/PluginClass( 8341): test this functionD/libEGL  ( 8341): loaded /system/lib/egl/libEGL_mali.soD/libEGL  ( 8341): loaded /system/lib/egl/libGLESv1_CM_mali.soD/libEGL  ( 8341): loaded /system/lib/egl/libGLESv2_mali.soD/OpenGLRenderer( 8341): Enabling debug mode 0I/HostClass( 8341): div::   packageName:com.example.plugin   dexPath:/data/app/com.example.plugin-1.apk   dexOutputDir:/data/data/com.example.host   libPath:/data/app-lib/com.example.plugin-1I/PluginClass( 8341): initializedI/PluginClass( 8341): test this function</span>


更多相关文章

  1. [置顶] 开发第一个Android设备驱动程序
  2. Android(安卓)Rom分区 与 SD卡读写
  3. Android加载大图防止OOM
  4. Cocos2dx 3.x在Android下多线程加载问题(thread exiting, not ye
  5. 解决Android(安卓)Studio 新建导入项目时死掉
  6. android扫描sdcard中的音视频及图片等文件
  7. Android(java)学习笔记127:Android(安卓)Studio新建工程中的build.g
  8. 如何在Android(安卓)Studio中使用Gradle发布项目至Jcenter仓库
  9. (六)android recovery 升级UI显示之资源文件

随机推荐

  1. Android(安卓)系统图标大全
  2. android Bitmap->BGR字节数组
  3. Android(安卓)系统完整的权限列表
  4. Android(安卓)Native CPU ABI Management
  5. android 实现透明按钮
  6. Android中的permission汇总(SDK1.5)
  7. Android(安卓)开发环境下载地址 -- 百度
  8. Android(安卓)SDK Platforms
  9. android相对布局简介
  10. Android使用WebView来显示天气预报