1

我们(http://www.mosync.com) 已经用 Android NDK 编译了我们的 ARM 重新编译器,它采用我们的内部字节码并生成 ARM 机器代码。当执行重新编译的代码时,我们看到性能有了巨大的提升,除了一个小例外,我们不能使用任何 Java 位图操作。本机系统使用一个函数来处理对重新编译的代码正在调用的 Java 端的所有调用。在 Java (Dalvik) 方面,我们绑定了 Android 功能。重新编译代码或执行机器代码时没有问题。完全相同的源代码适用于 Symbian 和 Windows Mobile 6.x,因此重新编译器似乎生成了正确的 ARM 机器代码。就像我说的,我们遇到的问题是我们不能使用 Java Bitmap 对象。我们已经验证了从 Java 代码发送的参数是正确的,我们已经尝试在 Android 自己的 JNI 系统中跟踪执行。问题是我们得到了一个 UnsupportedOperationException “大小必须适合 32 位。”。这个问题在 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

我设法找到了解决方法。当我将所有 Bitmap.createBitmap 调用包装在 Activity.runOnUiThread() 中时,它可以工作。

于 2011-09-21T11:35:51.000 回答