我想知道是否可以打包(或序列化)ClassLoader
以通过 Message
将其发送到 Android 中的另一个进程。 ClassLoader
没有实现 Parcelable
/Serializable
。
关于如何执行此操作的任何提示?提前致谢!
最佳答案
类加载器
类加载器基本上是一个哈希表,其条目以类名为键并指向加载到 VM 中的字节码。加载到 VM 本身的字节代码当然是 Java 进程的禁区,因为 Java 不允许您操作代码。请注意,字节码已由 JIT VM 编译为特定于 CPU 的代码,并将包含内存位置和其他低级结构。
可以在同一 VM 内共享类加载器(通过序列化或其他方式),因为类加载器仍然能够指向原始字节码.但是,为了序列化然后反序列化到另一个 VM,类加载器必须序列化字节代码。这就是问题所在。
序列化类加载器
作为一个思想实验,我们将如何序列化代码以便其他进程可以反序列化它?
我们必须将其作为类大小的 block 来处理,以便序列化实体具有整个类接口(interface)。我们将不得不“取消解析”字节码中指向符号的指针。我们还必须为该类复制整个字符串和符号表,以便内省(introspection)继续工作。
我们刚刚定义的是类文件本身(类成员的初始化与序列化略有不同)
让我重复一遍:类文件 是类的序列化版本。
DEX 难题
但是,Android 将类文件预编译到 DEX 中。这是一个包含 JAR 优化版本的单个文件 - 类彼此预先链接,所有字符串符号都位于相同的共享字符串/符号池中。因此,在 Android 中,最小的可共享组件是 DEX。
在许多情况下,应用程序或设备制造商会创建一个 ODEX 文件。这是一个针对特定 CPU 和架构(包括大端或小端系统)编译的 DEX 文件。
在 Android 中,您可以将 ODEX 文件视为序列化类加载器。
远程类加载
问题的症结在于一个进程如何加载对原始进程可见的类文件。 yorkw建议一个class loader他/她发现哪个做了我建议的事情。该方法是第一个进程实现类查找服务,返回类字节码。但是,由于上面列出的 DEX 问题,这不能直接在 Android 上运行。
解决方案?
因此,您实现的任何解决方案都将基于 (O)DEX。您基本上需要让您的客户端与您的服务器对话并请求 (O)DEX 文件,然后将其作为单个实体加载。加载它会返回你的新类加载器
现在,我从来没有这样做过,Android 完全有可能只允许加载一个 DEX 文件,从而破坏了这种方法。 YMMV
我希望这个讨论能有所帮助...
TL;DR 您不能序列化类加载器;然而,您可能能够说服另一个进程加载一个 (O)DEX 文件,这将产生相同的结果。
关于android - 包裹/序列化类加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11538472/