2017-09-01 42 views
-2

嗨,我使用基于jscheme一个Android应用程序(方案的Droid),但如果你不熟悉它,也许你很熟悉Clojure的。在任何情况下,这些提供访问虚拟机(jvm,dalvik)。在计算机上(任何拱门或操作系统),我都可以动态加载自己编译的类。但是,当我尝试在Android(加载dex'ed罐子)我遇到问题我不能修复:因此负载JAR/DEX动态地从Android应用

> (define inner-url-array (array java.net.URL.class (java.net.URL. "file:///sdcard/Test.jar"))) 
# (file:///sdcard/Test.jar) 
> (define systemClassLoader (ClassLoader.getSystemClassLoader)) 
dalvik.system.PathClassLoader[DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib, /vendor/lib, /system/lib, /vendor/lib]]] 
> (define arrlist (array java.lang.Class.class java.net.URL.class)) 
# (class java.net.URL) 
> (define classLoaderClass java.net.URLClassLoader.class) 
class java.net.URLClassLoader 
> (define method (.getDeclaredMethod class LoaderClass "addURL" arrlist)) 
protected void java.net.URLClassLoader.addURL(java.net.URL) 
> (.setAccessible method #t) 
#null 
> (.invoke method systemClassLoader inner-url-array) 
Expected receiver of type java.net.URLClassLoader, but got dalvik.system.PathClassLoader 

问题是ClassLoader.getSystemClassLoader即使我尝试转换为URLClassLoader类,它拒绝。然后我试图使用dalvik.system.DexClassLoader代替

> (import "dalvik.system.*") 
# t 
> (define classloader (DexClassLoader. "/sdcard/Test.jar" "/sdcard" #null (.getParent (ClassLoader.getSystemClassLoader)))) 

,现在我得到这个错误!:

优化的数据目录/ SD卡不被当前用户拥有。共享存储无法保护您的应用程序免受代码注入攻击。

它为什么会拒绝写入SD卡?是否有另一种解决方案来加载这样的jar文件,或者至少扩展应用程序的类路径?

回答

0

好的,我知道我的问题对于头脑简单的人来说太复杂了,技术太过了,但是从上面的CommonsWare提示我找到了一个解决方案(实际上有两个解决方案),我在这里发布它们,与更原始的程序员可以在将来从中受益,如果他们想稍微好一点成为:

(define loader (dalvik.system.DexClassLoader. "/sdcard/classes.dex" 
          "/data/data/net.meltingwax.schemedroid" 
          # null (ClassLoader.getSystemClassLoader))) 

1)“/data/data/net.meltingwax.schemedroid”是托管的应用程序和2的内部存储)更好地加载存储在classes.dex中的dex。

另一种方式(尽管可能很快会过时)使用PathClassLoader:

(define loader (dalvik.system.PathClassLoader. "/sdcard/classes.dex" 
          (ClassLoader.getSystemClassLoader))) 

其余的是相同的:

(define iclass (.loadClass loader "Test")) 

(define method (vector-ref (.getDeclaredMethods iclass) 0)) 

(.invoke method #null #("Aabc" "aAc")) 

,这就是它!

1

为什么会拒绝写入SD卡?

错误消息将用于读取操作,而不是写入操作。

至于为什么,错误信息是不言自明的。 Google不希望应用程序从不受信任的来源加载代码,例如external storage

是否有另一种解决方案来加载这样的jar文件或至少扩展应用程序的类路径?

有托管的应用程序下载DEX到internal storage的应用程序,验证该DEX不与(例如,已在DEX可以在签名JAR,你再验证包装)篡改,然后加载从DEX那里。

请注意,像这样的动态代码加载可能会违反您选择的应用程序分发渠道的服务条款,如果您计划根据此分发任何内容。

+0

“托管应用程序将DEX下载到应用程序的内部存储器中”。一个人会怎么做?当然内部存储是一个不适用于任何其他应用程序,所以复制/粘贴不起作用。托管应用程序不会下载东西 – francogrex

+0

@francogrex:“托管应用程序不下载东西” - 然后与托管应用程序的开发人员交谈,并要求他们添加一些内容以允许您执行您尝试的操作做。 – CommonsWare