正确使用Classloader(特别是在Android中)

11 java android classloader

我阅读了一些关于类加载器的文档,但我仍然不确定它们的位置和原因.Android API说:

从存储库加载类和资源.在运行时安装一个或多个类加载器.只要运行时系统需要一个尚未在内存中可用的特定类,就会查询这些内容.

因此,如果我理解这是正确的,那么可以有许多负责加载新类的classlaoders.但系统如何决定使用哪个?在哪种情况下,开发人员应该实例化一个新的类加载器?

在Intent的Android API中有一种方法

public void  setExtrasClassLoader  (ClassLoader  loader)
Run Code Online (Sandbox Code Playgroud)

描述说:

设置从此Intent的extras中解组任何Parcelable值时将使用的ClassLoader.

那么我可以定义一个特殊的类加载器,以便我可以使用未在接收活动中定义的Intent传递对象吗?一个例子:

如果位于项目A(在Eclipse中)的活动A使用Intent对象的putExtra定义了我想要发送到项目B中的活动B的对象.如果未定义通过Intent发送的此对象(项目B中的源代码),则存在NoClassDefFoundException.那么我可以使用方法setExtraClassloader来避免这种异常吗?如果是,我如何决定我必须通过哪个类加载器对象?我如何正确实例化它?

Com*_*are 12

我阅读了一些关于类加载器的文档,但我仍然不确定它们的位置和原因.

一般来说,您不需要触摸类加载器系统.

在哪种情况下,开发人员应该实例化一个新的类加载器?

经过大约十年的Java编程经验.:-)

如果位于项目A(在Eclipse中)的活动A使用Intent对象的putExtra定义了我想要发送到项目B中的活动B的对象.如果未定义通过Intent发送的此对象(项目B中的源代码),则存在NoClassDefFoundException.那么我可以使用方法setExtraClassloader来避免这种异常吗?

不,因为项目A和项目B无法共享代码.把你需要的课程放在两个项目中.或者使用带有AIDL的远程服务接口代替Intents和附加功能.或者不使用自定义类,而是将对象视为数据结构(例如,使用简单HashMapStrings或类似的东西).

  • @CommonsWare`否,因为项目A和项目B无法共享代码`... Eeeh ...但是我在这里使用的`createPackageContext`方法呢:http://stackoverflow.com/questions/5743485/android-resultreceiver-across-packages/7065677 #7065677 (2认同)
  • @Idolon:虽然该技术显然可行,但我不建议这样做。您没有办法强制两个项目都使用相同的代码库,除非您计划将枪支抬高所有用户的头脑。您需要能够应对独立更新的两个项目。这就要求设计一个能够在面对版本更改时保持健壮的API,并且我怀疑是否可以通过将类加载到其他项目之外来实现。 (2认同)

小智 9

这是一个迟到的答案,但希望它会帮助其他人.

通常,类加载器用于在运行时加载可执行的Java代码.一个很好的例子就是从互联网上下载的插件.您可以从类文件中获取二进制数据,加载它,并根据需要调用其中的函数.当然,您需要使用调用程序已知的接口或抽象类,以便它知道如何使用该类.

当典型庄园中无法访问二进制类数据时,将使用自定义类加载器.例如,如果您的蓝牙设备包含带有实现接口的代码的类文件,则需要编写自定义类加载器以通过蓝牙接口加载类数据.

您可能想要编写自定义类加载器的另一个原因是,如果要更改加载的类访问其他类的方式.您可以限制加载的类可以访问哪些内部类,甚至可以编写自己的类,从而更改内部类的行为.例如,如果加载的类使用Java.io.File类,则可能需要强制它使用内部类以不同的方式访问文件.

简而言之,当您编写自定义类加载器时,您可以更改类的加载方式,以及加载的类如何加载所有其他类.