【问题标题】:Problems using Rhino on Android在 Android 上使用 Rhino 的问题
【发布时间】:2011-04-21 00:47:43
【问题描述】:

我正在尝试在我的 Android 的 Java 应用程序中使用 Mozilla Rhino 来评估一些 JavaScript。我正在使用 Eclipse + ADT 插件。

首先,我尝试从 Mozilla 的网站下载 Rhino .jar 文件并将其作为 Eclipse 中的库添加到项目中。 Eclipse 很好地识别它并编译了应用程序。但是,在运行它时,我在调用 Context.evaluateReader() 时遇到异常(请参阅下面的堆栈跟踪)。

然后我尝试在 Eclipse 中将 Rhino 源代码添加为单独的 Android 项目,将其标记为库并在我的项目中引用它,这足以让 Eclipse 编译它,但导致了同样的错误。

这是我得到的堆栈跟踪 (java.lang.UnsupportedOperationException: can't load this type of class file)

Thread [<7> Thread-8] (Suspended (exception UnsupportedOperationException)) 
    DefiningClassLoader(ClassLoader).defineClass(String, byte[], int, int, ProtectionDomain) line: 338  
    DefiningClassLoader.defineClass(String, byte[]) line: 62    
    Codegen.defineClass(Object, Object) line: 159   
    Codegen.createScriptObject(Object, Object) line: 114    
    Context.compileImpl(Scriptable, Reader, String, String, int, Object, boolean, Evaluator, ErrorReporter) line: 2440  
    Context.compileReader(Reader, String, int, Object) line: 1326   
    Context.compileReader(Scriptable, Reader, String, int, Object) line: 1298   
    Context.evaluateReader(Scriptable, Reader, String, int, Object) line: 1137  
    TimetableProcessor.evaluate(InputStream, String, String[]) line: 31 
    TimetableProcessor.processBasicData(InputStream, String) line: 58   
    TimetableProcessor.process(InputStream, String) line: 52    
    TimetableUpdater.update() line: 53  
    Main$1$1.run() line: 22

我的代码中遇到异常的部分如下所示:

        Context cx = Context.enter();
        cx.setLanguageVersion(Context.VERSION_1_7);
        Scriptable scope = cx.initStandardObjects();
        try {
            Object result = cx.evaluateReader(scope, new InputStreamReader(data), /* <<< exception here */
                    filename, 0, null);
        } catch (IOException e) {
            // ...
        }

我还发现 this blog post 包含类似的代码并说它可以工作。作者说他使用了来自Android Scripting 站点的jar 文件。我在那里找到的唯一 jar 文件在 rhino_extras_r3.zip 中。但是,它不包含.class 文件,而是包含classes.dex 文件。当我将它作为库添加到 Eclipse 中时,它无法识别它包含的类,因此由于缺少对 Rhino 类的引用而无法编译我的项目。

感谢任何有关如何使其工作的帮助!

【问题讨论】:

    标签: java android rhino


    【解决方案1】:

    我终于让它工作了。我应该更加关注我链接的那篇博客文章。

    如果我添加行

    cx.setOptimizationLevel(-1);
    

    要禁用优化,一切正常。

    【讨论】:

    • 默认情况下,Rhino 会尝试动态生成 JVM 字节码,作为一种 Javascript JIT。这很酷,但 Android 不运行 JVM 字节码——它运行 Dalvik 字节码。因此,您必须通过您显示的代码 sn-p 禁用优化,以允许 Rhino 运行。
    • 你可以用V8代替rhino
    • 太棒了,帮了我很多:)
    • 你是如何包含库的?
    • 有道理。当动态添加类时,Dalvik 不能直接获取 Java 字节码。是否有符合 JSR 223 且非 GPL 的 RhinoScriptEngine?
    【解决方案2】:

    rhino1_7R2.jar 的 Android 兼容版本可在版本控制系统中的 SL4A 站点上找到。 Here is a sample project 将 Rhino 和 BeanShell 封装到 Android 解释器服务中。

    【讨论】:

    • 谢谢,我没有注意到那个 jar 文件,因为它没有在下载部分列出。它仍然没有解决我的问题(我已经发布了我的实际解决方案),但你绝对值得一票,因为你向我展示了 jar 文件的位置以及我可以用作示例的示例项目。
    【解决方案3】:

    我编写了一个库,可以在 Android 上运行 Rhino。

    优势包括:

    • Rhino 只能在优化级别 -1 上运行。该库支持所有级别。
    • 该库支持使用 JavaAdapter,这在基本 Rhino 中是不可能的。
    • 虽然我没有对此进行基准测试,但它应该会提高性能。 (编译代码比解释代码快)

    https://github.com/F43nd1r/rhino-android

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-01
      相关资源
      最近更新 更多