2010-10-04 4 views
17

J'essaie d'utiliser Mozilla Rhino dans mon application Java pour Android pour évaluer du JavaScript. J'utilise le plugin Eclipse + ADT.Problèmes d'utilisation de Rhino sur Android

J'ai d'abord essayé simplement de télécharger le fichier .jar de Rhino depuis le site Web de Mozilla et de l'ajouter au projet en tant que bibliothèque dans Eclipse. Eclipse l'a reconnu et a compilé l'application. Toutefois, lors de son exécution, je reçois une exception lors de l'appel Context.evaluateReader() (voir ci-dessous pour la trace de la pile). Puis j'ai essayé d'ajouter le code source de Rhino en tant que projet Android distinct dans Eclipse, en le marquant comme une bibliothèque et en le référençant dans mon projet, ce qui était suffisant pour qu'Eclipse le compile, mais a conduit à la même erreur .

C'est le stacktrace je reçois (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 

Le peu de mon code qui frappe l'exception ressemble à ceci:

 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) { 
      // ... 
     } 

J'ai aussi trouvé this blog post qui contient un code similaire et dit Ça marche. L'auteur dit qu'il a utilisé un fichier jar du site Android Scripting. Le seul fichier jar que j'ai trouvé était dans rhino_extras_r3.zip. Cependant, il ne contient pas de fichiers .class mais plutôt un fichier classes.dex. Lorsque j'ai ajouté cela en tant que bibliothèque dans Eclipse, il n'a pas reconnu les classes qu'il contient et n'a donc pas pu compiler mon projet à cause des références manquantes aux classes Rhino.

Toute aide sur comment faire fonctionner ceci est appréciée!

Répondre

32

J'ai finalement réussi à le faire fonctionner. J'aurais dû payer plus d'attention à ce blog que j'ai lié.

Si j'ajoute la ligne

cx.setOptimizationLevel(-1); 

pour désactiver Optimisations, tout fonctionne parfaitement.

+12

Par défaut, Rhino essaie de générer un bytecode JVM à la volée, comme une sorte de Javascript JIT. C'est cool et tout, mais Android n'exécute pas le bytecode JVM - il utilise le bytecode Dalvik. Par conséquent, vous devez désactiver l'optimisation, via l'extrait de code que vous avez montré, pour permettre à Rhino de s'exécuter. – CommonsWare

+0

Je confirme cela aide :-) – agibalov

+1

@Listill m faire face au même problème après avoir ajouté cette ligne .. –

11

Une édition compatible avec Android de rhino1_7R2.jar est disponible sur le site SL4A, dans le système de contrôle de version. Here is a sample project qui complète Rhino et BeanShell dans un service d'interprétation Android.

+0

Merci, je ne l'ai pas remarqué que jar parce qu'il ne figurait pas dans la section téléchargements. Cela n'a toujours pas résolu mon problème (j'ai posté ma solution actuelle), mais vous méritez certainement un upvote pour me montrer où le fichier jar est et le projet exemple que je peux utiliser comme exemple. –

+1

Voici le lien direct: http://code.google.com/p/android-scripting/source/browse/rhino/rhino1_7R2.jar –

1

J'ai écrit une bibliothèque qui permet d'exécuter Rhino sur Android.

Les avantages incluent:

  • Rhino ne peut fonctionner que sur le niveau d'optimisation -1. La bibliothèque prend en charge tous les niveaux.
  • La bibliothèque prend en charge l'utilisation de JavaAdapter, ce qui n'est pas possible avec la base Rhino.
  • Bien que je ne l'ai pas référencé, cela devrait donner une augmentation des performances. (Le code compilé est plus rapide que le code interprété)

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