Запуск сгенерированного машинного кода ARM на Android дает исключение UnsupportedOperationException с растровыми объектами Java - PullRequest
1 голос
/ 29 августа 2011

Мы (http://www.mosync.com) скомпилировали наш компилятор ARM с помощью Android NDK, который берет наш внутренний байт-код и генерирует машинный код ARM.При выполнении перекомпилированного кода мы видим огромное увеличение производительности, за одним небольшим исключением, мы не можем использовать какие-либо операции с битовой картой Java.Нативная система использует функцию, которая заботится обо всех вызовах на стороне Java, которые вызывает перекомпилированный код.На стороне Java (Dalvik) у нас есть привязки к функциям Android.Нет проблем при перекомпиляции кода или при выполнении машинного кода.Точно такой же исходный код работает на Symbian и Windows Mobile 6.x, поэтому кажется, что перекомпилятор генерирует правильный машинный код ARM.Как я уже сказал, проблема в том, что мы не можем использовать объекты Java Bitmap.Мы убедились, что параметры, отправляемые из кода Java, верны, и мы попытались проследить за выполнением в собственных системах JNI Android.Проблема в том, что мы получаем UnsupportedOperationException с «размер должен соответствовать 32 битам».Проблема кажется последовательной на Android 1.5 до 2.3.Мы не пробовали перекомпиляцию на устройствах Android 3.

Это ошибка, с которой сталкивались другие люди, я думаю, другие разработчики сделали подобные вещи.

Ответы [ 2 ]

0 голосов
/ 21 сентября 2011

Мне удалось найти обходной путь. Когда я оборачиваю все вызовы Bitmap.createBitmap внутри Activity.runOnUiThread (), это работает.

0 голосов
/ 29 августа 2011

Я нашел сообщение в 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 и значения всех аргументов, которые вы ему передаете, может быть легче найти причину.

...