能否从SD卡上的JAR库动态加载Activity类并实际使用它?

14
我在sdCard上有一个.jar文件(我使用dx工具将通常的.jar编译为dex,否则Android在运行时会出现问题)
我想要使用的类实际上是Activity,并且通过“使用”我指的是Inflate!
A)我注意到如果像这样加载类,则加载的类将具有父类的包作为其父级包(其中我运行代码的包:例如:jar库中类的真实包:“com.something”和我的应用程序包:“com.wonderfull” - >加载的类在“com.wonderfull.com.something”中:))。
B)在“最佳”情况下,我会收到此错误:
无法实例化活动ComponentInfo {com.appno2 / com.appno1.futureLib.LibActivity}: java.lang.ClassNotFoundException:dalvik.system.PathClassLoader [/ data / app / com.appno2-1.apk]中的com.appno1.futureLib.LibActivity加载器中的com.appno1.futureLib.LibActivity
C)在清单中,我已经将Activity(要动态加载的Activity)放置在以下位置:
activity     android:name =“com.appno1.futureLib.LibActivity”     android:label =“@string/app_name”> /活动> 所以我重复标题中的问题:是否可能从sd卡上的jar库中动态加载Activity类并实际使用它?
如果问“为什么要这样做?”-只是好奇!作为概念:用户输入有效许可证后,下载应用程序实际代码的可能性(以jar或其他形式)
更新: -此想法适用于片段(意味着要导入的类是一个片段)
当前结论: -可能将Java类甚至是Android UI相关类放在外部.jar(例如在sd卡上,或从Internet下载..etc),并在需要时动态加载它们。哦,是的:您无法以这种方式使用活动 :( ..可能甚至不会使用服务..
更多信息#1: Is it possible to dynamically load a library at runtime from an Android application? 更多信息#2: http://android-developers.blogspot.ro/2011/07/custom-class-loading-in-dalvik.html 关于URLClassLoader:这样可以工作(不涉及DalvikClassLoader-ClassNotFoundException&&显然:仍然无法像这样加载的Activity膨胀)
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);

嗨,@pulancheck1988,有办法解决吗? - Nitesh
你好,这个问题有解决方案吗?我遇到了java.lang.ClassNotFoundException的问题,因为加载器显然没有搜索“更新”的DexPathList。 - user2587965
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,则问题可能得到解决。


嗨。 所以:活动在jar(来自sdCard)中..如果我创建对象的实例并检查类类型-> Activity,那么这很好!在清单中,我有“com.appno1.futureLib.LibActivity”(我也尝试过没有“com.appno1.”的情况...无论如何,如果这是错误的->错误会包含“您是否确定已在清单中声明了xxx??”)->似乎合法!但我仍然得到“ClassNotFoundException:com.appno1.futureLib.LibActivity在加载器中 ”..下一个测试我将故意更改.classpath文件。 - pulancheck1988
whogiawho,你怎么注册这个活动? - Ivan
@Ivan 要注册一个活动,您需要在调用应用程序的 AndroidManifest.xml 中创建一个新的 <activity> 标签,就像 @whogiawho 上面演示的那样。 - Kenny Worden

0
你可以扫描JAR文件的内容并使用URLClassloader加载类。这是标准的Java(如果您想查看,我有一个JavaSE实现),但它包含在Android API中,所以我认为它应该可以正常工作。
{{link1: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中为您提取类。


URLClassLoading 可以工作,但是必须涉及到 DalvikClassLoader,否则会出现 ClassNotFoundException - 因为 jar 实际上包含 dex 类(它可以是 .apk,.zip 文件).. 我在问题中添加了一些代码(我可以在那里更好地格式化它)。 - pulancheck1988
你会遇到权限问题!每个活动都应在清单中定义! - Korniltsev Anatoly
@KorniltsevAnatoly @pulancheck1988 有一个叫做 dalvik.system.PathClassLoader 的东西,我认为它类似于 URLClassLoader - Powerslave
我不知道它是否已经解决,但无论如何...在应用程序中添加一些主机活动,然后加载视图或片段怎么样? - Powerslave
你好,借助Fragment,你可以轻松实现它。 - User10001

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接