1

私たち ( http://www.mosync.com) は、内部バイト コードを取得して ARM マシン コードを生成する Android NDK を使用して ARM リコンパイラをコンパイルしました。再コンパイルされたコードを実行すると、パフォーマンスが大幅に向上しますが、1 つの小さな例外を除いて、Java Bitmap 操作は使用できません。ネイティブ システムは、再コンパイルされたコードが呼び出している Java 側へのすべての呼び出しを処理する関数を使用します。Java (Dalvik) 側では、Android 機能へのバインディングがあります。コードの再コンパイル時またはマシン コードの実行時に問題はありません。まったく同じソース コードが Symbian と Windows Mobile 6.x で機能するため、再コンパイラは正しい ARM マシン コードを生成するようです。前述したように、問題は Java Bitmap オブジェクトを使用できないことです。Java コードから送信されるパラメータが正しいことを確認しました。そして、Android 独自の JNI システムで実行を追跡してみました。問題は、「サイズは 32 ビットに収まる必要があります」という UnsupportedOperationException が発生することです。問題は Android 1.5 から 2.3 で一貫しているようです。Android 3 デバイスでリコンパイラを試したことはありません。

これは他の人が遭遇したバグですか? 他の開発者も同様のことをしていると思います.

4

2 に答える 2

0

dalvik_system_VMRuntime.cでメッセージを見つけました:

/*
 * public native boolean trackExternalAllocation(long size)
 *
 * Asks the VM if <size> bytes can be allocated in an external heap.
 * This information may be used to limit the amount of memory available
 * to Dalvik threads.  Returns false if the VM would rather that the caller
 * did not allocate that much memory.  If the call returns false, the VM
 * will not update its internal counts.
 */
static void Dalvik_dalvik_system_VMRuntime_trackExternalAllocation(
    const u4* args, JValue* pResult)
{
    s8 longSize = GET_ARG_LONG(args, 1);

    /* Fit in 32 bits. */
    if (longSize < 0) {
        dvmThrowException("Ljava/lang/IllegalArgumentException;",
            "size must be positive");
        RETURN_VOID();
    } else if (longSize > INT_MAX) {
        dvmThrowException("Ljava/lang/UnsupportedOperationException;",
            "size must fit in 32 bits");
        RETURN_VOID();
    }
    RETURN_BOOLEAN(dvmTrackExternalAllocation((size_t)longSize));
}

このメソッドは、たとえば GraphicsJNI::setJavaPixelRef から呼び出されます。

size_t size = size64.get32();
jlong jsize = size;  // the VM wants longs for the size
if (reportSizeToVM) {
    //    SkDebugf("-------------- inform VM we've allocated %d bytes\n", size);
    bool r = env->CallBooleanMethod(gVMRuntime_singleton,
                                gVMRuntime_trackExternalAllocationMethodID,
                                jsize);

あなたが呼び出しているコードが大きすぎるサイズを割り当てようとしているようです。失敗した実際の Java 呼び出しと、それに渡すすべての引数の値を示すと、理由を見つけやすくなります。

于 2011-08-29T10:29:54.750 に答える
0

回避策を見つけることができました。Activity.runOnUiThread() 内ですべての Bitmap.createBitmap 呼び出しをラップすると、機能します。

于 2011-09-21T11:35:51.000 に答える