是否可以从sdCard&上的jar库动态加载Activity类。实际上用它?

时间:2012-10-19 14:52:41

标签: android classloader dex

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

我想要使用的课程实际上是一个活动&通过“使用”我的意思是膨胀!

A)我注意到如果我像这样加载类,加载的类将包含parrent类的包(我运行代码的那个:示例:类的真实包)在jar库中:“com.something”& my-app-package:“com.wonderfull” - >加载的类位于“com.wonderfull.com.something”:)) - > retested:它保留原始包,就像在库中一样

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

  

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

C)在清单中,我放置了Activity(这是一个可以加载的动态):

活性     机器人:名字= “com.appno1.futureLib.LibActivity”     android:label =“@ string / app_name”> /活性GT;

所以我从标题重复提问:是否有可能从sdCard&上的jar库中加载一个Activity类。实际使用它?

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

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

目前的结论: - 可能有:lame java类甚至是外部.jar中的android UI相关类(例如,在sdCard上,或者从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

Regardin 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);

2 个答案:

答案 0 :(得分: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,问题可能会解决。

答案 1 :(得分:0)

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

URLClassloader on developer.android.com

基本上你得到一个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中的类。