7

Android Jasper Reportingの回答を見つけようとしたところ、他に2つの質問があることがわかりました。これらの質問は、回答ではなく質問として尋ねられました;):

私の質問は今です:「デバイス上で直接使用するコンパイラはありますか」そして「デバイスをroot化せずにそのようなものを実行する方法。誰かが私にヒントを与えることができれば私は本当に感謝します...


私はこのアプローチを少し楽しみにして、root化されていないAndroidデバイスでAPKを直接作成できるアプリを見つけました:

eclipseのコンパイラと移植されたdexコンバータを使用しているようです。今、私は同じことをする方法を理解しようとしています。

確かに:ソースコードを入手して調べてください。しかし、サーバーへの接続を取得してそれを解決しようとすると、不思議な問題が発生しますが、私はここでこの質問をするようにとの嘆願に従います。他の人を助けることと、自分自身の答えを得ることの両方を望んでいます;)


インディゴのプラグインディレクトリからorg.eclipse.jdt.core_3.7.3.v20120119-1537.jarを取得し、次のコードを試しました。

     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!!!");

java.lang.Objectが見つからないという例外がスローされることもあれば、100%の使用率でプロセッサを加熱しているときに何も実行せずにスタックすることもありました... ...

現時点では、何が起こっているのか、そしてその理由を理解できませんでした。そして、私がこの部分を行うために他の仕事をしているので、少し待たなければなりません。

4

1 に答える 1

5

私はJavaIDEdroidのソースからインスピレーションを得て、私が愚かであることに気づいた後、成功しました (しばらくの間、デバイス上の dexified フレームワーク クラスでコンパイラを使用しようとしましたが、当然動作しませんでした)。
sdcard 上の ADTs android-jar のコピーを使用して Test.java のコンパイルに成功した後、DexClassLoader を使用してクラスをロードするだけで済みました。
それを行う方法について自分自身に通知しているときに、Dalvik でのカスタム クラスの読み込みという素晴らしい記事を見つけました。少なくともこのコードを書くきっかけになりました。

    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();
    }

Test.java には次の 1 つのメソッドのみが含まれます。

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

実行するには、jars jdt-compiler-xxxjar (eclipse の plugins ディレクトリにあります) と dx.jar (Android SDK のディレクトリ platform-tools/lib にあります) が必要です。


それほど難しいことではありません;)
そして、愛するAndroidデバイスで動作させるために、JasperReportsのソースで何を変更すればよいかを見つけます:D

于 2012-06-27T13:53:40.117 に答える