Android基于类装载器插件架构的实现_第1页
Android基于类装载器插件架构的实现_第2页
Android基于类装载器插件架构的实现_第3页
Android基于类装载器插件架构的实现_第4页
Android基于类装载器插件架构的实现_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 9 Android 基于类装载器的插件架构的实现基于类装载器的插件架构的实现 自己 2012 年 9 月份实践成功 然后总结的文档 以备以后查看 目录目录 Android 基于类装载器的插件架构的实现 1 1 类装载器的介绍 1 2 PathClassLoader 的实践 2 2 1 apk 插件的实现 2 2 1 1 插件编码的实现 2 2 1 2 生成插件 apk 2 2 2 编写主程序 apk 2 2 3 执行结果 4 3 DexClassLoader 的实践 4 3 1 编写接口和实现 4 3 1 1 接口类 InterfacePlug 4 3 1 2 实现类 PlugImpl 4 3 2 打包并转化为 dex 5 3 3 编写主程序 apk 5 3 4 执行结果 7 4 更改为插件架构 7 4 1 插件实现 7 4 2 相关主调用程序 9 4 3 执行结果如下所示 9 1 类装载器的介绍 类装载器的介绍 在 Java 里面 我们可以把一些类放到 jar 文件里面 然后用 ClassLoader 动态加载 Class 文件 但是在 Android 上面 情况有所不同 首先第一个是 jar 文件的制作 Java 里面直接把 class 文件打包到 jar 文件里面就可 以了 但是 Android 的 Dalvik VM 是不认 Java 的 byte code 的 所以不能直接这么打包 而要用 dx 工具转成 Dalvik byte code 才可以 当然 dx 工具转了之后 jar 包里面就不是 class 文件了 而是 dex 文件 第二个是 Android 里面虽然也提供了 URLClassLoader 的实现 但是并不能用 在 Android 里 要动态加载其它类 可以用的 Class Loader 有 DexClassLoader 和 PathClassLoader PathClassLoader 只能加载已经安装到 Android 系统中的 apk 文件 也就是 data app 目录下的 apk 文件 其它位置的文件加载的时候都会出现 ClassNotFoundException 2 9 DexClassLoader 可以加载 apk jar 或者 dex 文件 而且可以加载 sdcard 下面的文件 下面主要通过例子讲解 DexClassLoader 和 PathClassLoader 的用法 2 PathClassLoader 的实践的实践 2 1 apk 插件的实现插件的实现 新建 android 工程 工程目录如下 2 1 1 插件编码的实现插件编码的实现 MyPlugApkActivity 为 android 新建工程默认创建的 Activity 程序 plugClass 的实现如下 package com apkplug import android util Log public class plugClass public plugClass Log d plugClass plugClass is initialized public int plugfunction int a int b return a b 2 1 2 生成插件生成插件 apk 在虚拟器上启动这个程序 在 app data 目录下生成 com plugapk 1 apk 文件 如下图 所示 2 2 编写主程序编写主程序 apk 新建一个 android 工程 主程序实现如下 package com host 3 9 import java io IOException import java lang reflect Method import android app Activity import android os Bundle import android util Log import android widget Toast import dalvik system DexClassLoader public class MyhostActivity extends Activity private final String TAG MyhostActivity private TextView tv null Override public void onCreate Bundle savedInstanceState super onCreate savedInstanceState setContentView R layout main tv TextView findViewById R id textView1 useDexClassLoader public void useDexClassLoader String dexPath app data com apkplug 1 apk String dexOutputDir data data com host PathClassLoader cDexClassLoader new PathClassLoader dexPath this getClass getClassLoader try Classclass1 cDexClassLoader loadClass com apkplug plugClass Object obj class1 newInstance Class params new Class 2 params 0 Integer TYPE params 1 Integer TYPE Method action class1 getMethod ApkPlugfunction params Integer ret Integer action invoke obj 12 13 tv setText method action getName return ret catch Exception e TODO handle exception 4 9 2 3 执行结果执行结果 3 DexClassLoader 的实践的实践 3 1 编写接口和实现编写接口和实现 3 1 1 接口类接口类 InterfacePlug package com plug public interface InterfacePlug public String function 01 public int function 02 int a int b 3 1 2 实现类实现类 PlugImpl package com plug import com plug InterfacePlug public class PlugImpl implements InterfacePlug Override public String function 01 return null Override public int function 02 int a int b return a b 5 9 3 2 打包并转化为打包并转化为 dex 将打包好的 Myplug jar 拷贝到 SDK 安装目录 android sdk windows platform tools 下 DOS 进入这个目录 执行命名 dx dex output Myplugdex jar Myplug jar dx 工具参数意义如下 dex 产生一个 dex 格式的文件 output 指定输出的文件名 等号右面第一个为生成的 dex 格式的文件 第二个为要转行的 jar 包文件 3 3 编写主程序编写主程序 apk 新建一个 android 工程 activity 实现如下 package com host import java io IOException import java lang reflect Method 6 9 import android app Activity import android os Bundle import android util Log import android widget Toast import dalvik system DexClassLoader public class MyhostActivity extends Activity private final String TAG MyhostActivity Override public void onCreate Bundle savedInstanceState super onCreate savedInstanceState setContentView R layout main useDexClassLoader public void useDexClassLoader String dexPath mnt sdcard Myplugdex jar String dexOutputDir data data com host try Runtime getRuntime exec rm data data com host Myplugdex dex catch IOException e1 TODO Auto generated catch block e1 printStackTrace DexClassLoader cDexClassLoader new DexClassLoader dexPath dexOutputDir null this getClass getClassLoader try Classclass1 cDexClassLoader loadClass com plug PlugImpl Object obj class1 newInstance Class params new Class 2 params 0 Integer TYPE params 1 Integer TYPE Method action class1 getMethod function 02 params Integer ret Integer action invoke obj 12 13 tv setText method action getName return ret catch Exception e TODO handle exception DexClassLoader 构造函数参数 含义 7 9 第一个参数 要加载的目标类所在 jar 包或 apk 的路径 本例中为 data app Myplugdex jar 第二个参数 由于要加载的 dex 文件的存放路径 本例中为 data data com host 第三个参数 目标类中所使用的 C C 库存放的路径 第四个参数 该装载器的父装载器 一般为当前执行类的装载器 创建了DexClassLoader对象后 调用loadClass 装载指定的类 Classclass1 cDexClassLoader loadClass com plug PlugImpl 3 4 执行结果执行结果 启动模拟器 把 Myplugdex jar push 到 mnt sdcard 目录下 执行结果为 虚拟器目录在com host下面多了一个解压的文件Myplugdex dex 如下图所示 4 更改为插件架构更改为插件架构 上面 ClassLoader 装载的类 调用其内部函数 需要首先构造出 Method 对象 并构造 出 Method 对象及其所使用的参数对象 然后才能调用 现在介绍一种简单的直接类引用 的方法调用其函数 4 1 插件实现插件实现 插件的接口类代码同3 1节 接口类代码改为 package com plug import com plug InterfacePlug 8 9 public class PlugImpl implements InterfacePlug Override public String function 01 return null Override public int function 02 int a int b return a b 导出后jar包后转为dex 需要注意点是 导出jar包时 只导出实现类 否则会出现Class ref in pre verified class resolved to unexpected implementation的错误 即重复定义 导出过 程如图4 1 图4 1 Mypulg导出jar包 其中接口类同时存在于接口类同时存在于插件工程和主调用工程 同时参与两个项 目的编译 接口类所在的文件包名要和主调用程序中的接口类所在包名一致 实现类可以接口类所在的文件包名要和主调用程序中的接口类所在包名一致 实现类可以 和不一致 和不一致 项目结构如下图所示 9 9 图4 1 插件工程Myp

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论