2012-06-27 2 views
5

Bei dem Versuch, eine Antwort auf Android Jasper Reporting ich herausgefunden zu finden, dass es zwei weitere Fragen dafür beantwortet werden, die ich gebeten worden, als eine Frage zu stellen, nicht als Antwort;):Wie implementiere ich einen Java-Compiler und einen DEX-Konverter in eine Android App?

Meine Fragen sind nun: „gibt es einen Compiler, um direkt auf dem Gerät zu verwenden“ AND „, wie diese ausgeführt werden, ohne das Gerät Verwurzelung. Wenn mir jemand einen Tip geben könnte ich es wirklich schätzen würde ...


sah ich ein wenig Zeit vorwärts bei diesem Ansatz und fand Apps, die es ermöglicht, APKs direkt auf einem Android-Gerät, das nicht gerootet ist zu erstellen:

Sieht aus wie sie den Compiler von Eclipse und eine portierte dex-Wandler verwenden. Jetzt versuche ich herauszufinden, wie man das Gleiche macht.

Sicher: Holen Sie sich den Quellcode und schauen Sie hinein. Aber während ich neugierige Probleme habe, eine Verbindung zu den Servern herzustellen und zu versuchen, sie zu lösen, folge ich der Bitte, diese Frage hier zu stellen. Hoffnung, beide andere mit ihm zu helfen, und auch eine Antwort für mich bekommen;)


ich die org.eclipse.jdt.core_3.7.3.v20120119-1537.jar vom Plugin nahm Verzeichnis meiner Indigo und versucht folgenden Code:

 org.eclipse.jdt.internal.compiler.batch.Main ecjMain = new org.eclipse.jdt.internal.compiler.batch.Main(new PrintWriter(System.out), new PrintWriter(System.err), false/*noSystemExit*/, null, progress); 
    System.err.println("compiling..."); 
    ecjMain.compile(new String[] {"-classpath", "/system/framework", storage.getAbsolutePath()+"/Test.java"}); 
    ecjMain.compile(new String[] {storage.getAbsolutePath()+"/Test.java"}); 
    System.err.println("compile succeeded!!!"); 

Manchmal wurde die Ausnahme ausgelöst, dass java.lang.Object nicht gefunden werden konnte und othertimes es nichts stecken zu tun, während mein Prozessor mit 100% Nutzung Erwärmung ... ...

Zu dieser Zeit konnte ich nicht herausfinden, was passiert und warum. Und weil ich andere Arbeiten machen muss, muss dieser Teil etwas warten.

+1

Ihre Frage hat nichts mit [tag: compiler-construction] zu tun. Sie erstellen keinen Compiler. Nicht wahllos markieren. – EJP

Antwort

1

Ich war erfolgreich nach der Inspiration von der Quelle JavaIDEdroid und erkannte, dass ich dumm bin (für eine Zeit habe ich versucht, den Compiler mit den dexified Framework-Klassen auf dem Gerät zu verwenden - die natürlich nicht funktionieren konnte).
Nachdem ich meine Test.java mit einer Kopie von ADTs Android-Jar auf SD-Karte kompiliert hatte, musste ich nur die Klassen mit dem DexClassLoader laden.
Während informiert myselft darüber, wie zu tun, dass ich diesen schönen Artikel Custom Class Loading in Dalvik gefunden, die mich zumindest inspiriert dieses Stück Code zu schreiben:

File storage = getDir("all41", Context.MODE_PRIVATE); 


    System.err.println("copying the android.jar from asssets to the internal storage to make it available to the compiler"); 
    BufferedInputStream bis = null; 
    OutputStream dexWriter = null; 
    int BUF_SIZE = 8 * 1024; 
    try { 
      bis = new BufferedInputStream(getAssets().open("android.jar")); 
      dexWriter = new BufferedOutputStream(
       new FileOutputStream(storage.getAbsolutePath() + "/android.jar")); 
      byte[] buf = new byte[BUF_SIZE]; 
      int len; 
      while((len = bis.read(buf, 0, BUF_SIZE)) > 0) { 
       dexWriter.write(buf, 0, len); 
      } 
      dexWriter.close(); 
      bis.close(); 

    } catch (Exception e) { 
     System.err.println("Error while copying from assets: " + e.getMessage()); 
     e.printStackTrace(); 
    } 


    System.err.println("instantiating the compiler and compiling the java file"); 
    org.eclipse.jdt.internal.compiler.batch.Main ecjMain = new org.eclipse.jdt.internal.compiler.batch.Main(new PrintWriter(System.out), new PrintWriter(System.err), false/*noSystemExit*/, null); 
    ecjMain.compile(new String[] {"-classpath", storage.getAbsolutePath()+"/android.jar", Environment.getExternalStorageDirectory().getAbsolutePath() + "/Test.java"}); 


    System.err.println("calling DEX and dexifying the test class"); 
    com.android.dx.command.Main.main(new String[] {"--dex", "--output=" + storage.getAbsolutePath() + "/Test.zip", Environment.getExternalStorageDirectory().getAbsolutePath() + "/./Test.class"}); 


    System.err.println("instantiating DexClassLoader, loading class and invoking toString()"); 
    DexClassLoader cl = new DexClassLoader(storage.getAbsolutePath() + "/Test.zip", storage.getAbsolutePath(), null, getClassLoader()); 
    try { 
     Class libProviderClazz = cl.loadClass("Test"); 
     Object instance = libProviderClazz.newInstance(); 
     System.err.println(instance.toString()); 
    } catch (Exception e) { 
     System.err.println("Error while instanciating object: " + e.getMessage()); 
     e.printStackTrace(); 
    } 

Die Test.java enthält nur eine Methode:

public String toString() { 
    return "Hallo Welt!"; 
} 

Um es laufen zu lassen, benötigen Sie die jars jdt-compiler-xxxjar (im plugins-Verzeichnis von eclipse) und dx.jar


Nicht wirklich hart (in Verzeichnisplattform-tool/lib von Android SDK);)
Und nun will ich herausfinden, was in der Quelle von Jasper ändern es auf unseren geliebten Android-Geräte zu bekommen arbeiten: D

Verwandte Themen