包/序列化ClassLoader

时间:2012-07-18 09:38:40

标签: android classloader serializable parcelable

我想知道是否可以包裹(或序列化)ClassLoader通过Message将其发送到Android中的其他进程。 ClassLoader未实施Parcelable / Serializable

有关如何执行此操作的任何提示?提前谢谢!

3 个答案:

答案 0 :(得分:2)

类加载器

类加载器基本上是一个哈希表,其条目由类名键控,并指向VM中加载的字节代码。加载在VM本身的字节代码当然不受Java进程的限制,因为Java不允许您操作代码。请注意,字节码已由JIT VM编译为特定于CPU的代码,并包含内存位置和其他低级构造。

可以在同一个VM 中共享类加载器(通过序列化或其他方式),因为类加载器仍然可以指向原始字节代码。但是,为了序列化然后反序列化到另一个VM,类加载器必须序列化字节代码。而且存在问题。

序列化类加载器

作为一个思想实验,我们如何序列化代码以便其他进程可以反序列化它?

我们必须将其作为类大小的块处理,以便序列化实体具有整个类接口。我们必须将字节码中的指针“解析”为符号。我们还必须复制该类的整个字符串和符号表,以便内省继续工作。

我们刚刚定义的是类文件本身(稍微不同的是类成员的初始化与序列化)

让我再说一遍:类文件 类的序列化版本。

DEX难题

但是,Android会将类文件预编译到DEX中。这是一个包含JAR优化版本的单个文件 - 类之间相互预先链接,所有字符串符号都位于相同的共享字符串/符号池中。因此,在Android中,您最小的可共享组件是DEX。

在许多情况下,应用或设备制造商会创建一个ODEX文件。这是一个已编译为特定CPU和体系结构(包括big-endian或little-endian系统)的DEX文件。

在Android中,您可以将ODEX文件视为序列化类加载器。

远程类加载

问题的关键在于一个进程如何加载原始进程可见的类文件。 yorkw建议class loader他/他找到了类似我建议的内容。方法是第一个进程实现一个类查找服务,返回类字节码。但是,由于上面列出的DEX问题,这不能直接在Android上运行。

解?

因此,您实施的任何解决方案都将基于(O)DEX。您基本上需要让您的客户端与您的服务器通信并请求(O)DEX文件,然后将其作为单个实体加载。加载它将返回新的类加载器

现在,我从未这样做过,Android完全有可能只允许加载一个DEX文件来破坏这种方法。 YMMV

我希望这次讨论有所帮助......


TL; DR 您无法序列化类加载器;但是可能能够说服另一个进程加载(O)DEX文件,这会产生相同的结果。

答案 1 :(得分:1)

不,不幸的是,这是不可能的。 ClassLoader的某些子集可能可以生成parcelable,但我真的建议反对它。

如果你的问题是你试图从另一个应用程序中的Parcel读取自定义类,你应该能够通过将类复制到另一个应用程序来读取它(确保它在两个应用程序中相同的包)。您所要做的就是在第一个应用程序中将它写入这样的包裹:

parcel.writeParcelable(myCustomParcelable, 0);

另一方面,在收到包裹的地方,请按照以下方式阅读:

MyCustomParcelable myCustomParcelable = (MyCustomParcelable)parcel.readParcelable(getClassLoader());

答案 2 :(得分:1)

鉴于ClassLoader的强大本机组件以及它的作用,我无法想象以任何方式与其他进程共享ClassLoader,至少不会以任何有意义的方式共享。