14

我在 sdCard 上有 1 个 .jar 文件(我使用 dx 工具将通常的 .jar 编译为 dex .. 否则 android 会在运行时抱怨)

我想使用的课程实际上是一个活动,“使用”我的意思是充气!

A)我注意到,如果我像这样加载类,加载的类将作为包 parrent 的包 parrent 类(我在其中运行代码的包:示例:jar 库中类的真实包:“com .something" & my-app-package: "com.wonderfull" -> 加载的类在 "com.wonderfull.com.something" :) ) -> 重新测试:它保留原始包,就像在库中一样

B)在“最佳”情况下,我收到此错误:

无法实例化活动 ComponentInfo{com.appno2/com.appno1.futureLib.LibActivity}:java.lang.ClassNotFoundException:com.appno1.futureLib.LibActivity 在加载器 dalvik.system.PathClassLoader[/data/app/com.appno2-1 .apk]

C)在清单中,我已经像这样放置了 Activity (要动态加载的那个):

活动 android:name="com.appno1.futureLib.LibActivity" android:label="@string/app_name" > /activity>

所以我重复标题中的问题:是否可以从 sdCard 上的 jar 库动态加载 Activity 类并实际使用它?

如果是“你为什么要这个?” - 只是古玩!+ 作为一个概念:在用户输入有效许可证后立即下载应用程序的实际代码(以某种罐子的形式)的可能性

更新: - 这个想法适用于片段(意味着要导入的类是片段)

目前的结论: - 可能有:蹩脚的java类甚至android UI相关的外部.jar(例如在sdCard上,或从互联网下载..等)并在需要时动态加载它们。哦,是的:你不能以这种方式工作这些活动:( .. 可能甚至没有服务..

更多信息 #1:是否可以在运行时从 Android 应用程序动态加载库?

更多信息#2:http ://android-developers.blogspot.ro/2011/07/custom-class-loading-in-dalvik.html

关于URLClassLoader:这有效(不涉及 DalvikClassLoader - ClassNotFoundException && obviosly:仍然不能膨胀像这样加载的活动)

File file = new File("/sdcard/myLib.jar");
File tmpDir = getDir("dex", 0);
ClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader());
DexClassLoader classloader = new DexClassLoader(file.getAbsolutePath(), tmpDir.getAbsolutePath(), null, loader);
Class<Object> classref = (Class<Object>) classloader.loadClass("packageInLib.ClassName");
Object myInstance = classref.getConstructor().newInstance();

Or instead of "loadClass"
Class<?> classref = Class.forName("packageInLib.ClassName", true, dalvikClassLoader);
4

2 回答 2

1

我有类似的场景。

如果你不把下面的代码放在 AndroidManifest.xml

<activity android:name="com.appno1.futureLib.LibActivity" android:label="@string/app_name" > </activity>

你会得到以下错误。

10-21 17:04:25.860: E/AndroidRuntime(11050): Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {... ...}; have you declared this activity in your AndroidManifest.xml?

但是,如果您在客户端应用程序中注册活动,则会得到 java.lang.ClassNotFoundException。

加载程序尝试在 [/data/app/com.appno2-1.apk] 中搜索 com.appno1.futureLib.LibActivity。显然这不是预期的。我相信 com.appno.futureLib.LibActivity 位于 .jar 文件中。

如果有办法让加载器在.jar文件中搜索LibActivity,问题可能就解决了。

于 2012-10-21T09:36:54.770 回答
0

您可以扫描 JAR 文件的内容并使用 URLClassloader 加载类。它是标准的 Java(如果你想看一下,我有一个 JavaSE 实现),但它包含在 Android API 中,所以我认为它应该可以正常工作。

developer.android.com 上的 URLClassloader

基本上你会得到一个 ClassLoader(脏代码警告!):

File file = new File("/sdcard/jars/myDynamicLib.jar");
ClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader());

您需要元数据 XML 或任何描述要加载的内容:

jar.getInputStream(jar.getEntry("myMetaData.xml"));

你加载信息(你解析它的方式取决于你使用的格式:你也可以让它已经加载到你的应用程序中)——现在你有了类名。

现在您只需尝试加载:

Class<?> classref = Class.forName(className, true, loader);
instance = (MyType) classref.getConstructor().newInstance();

同样,虽然我没有在 Droid 上尝试过这样的事情,但我认为这应该可以正常工作。

这就弥补了。您需要 JAR 文件的路径以及要加载的类的名称。类加载器将为您将类从 JAR 中拉出。

于 2012-10-21T16:51:05.423 回答