我们(http://www.mosync.com)已经使用Android NDK编译了我们的ARM重新编译器,它采用我们的内部字节代码并生成ARM机器代码。执行重新编译的代码时,我们看到性能大幅提升,但有一个小例外,我们不能使用任何Java Bitmap操作。 本机系统使用一个函数来处理重新编译的代码正在调用的Java端的所有调用。在Java(Dalvik)方面,我们将绑定到Android功能。重新编译代码或执行机器代码时没有问题。完全相同的源代码适用于Symbian和Windows Mobile 6.x,因此重新编译器似乎生成正确的ARM机器代码。 就像我说的,我们遇到的问题是我们不能使用Java Bitmap对象。我们已经验证了从Java代码发送的参数是正确的,我们已经尝试在Android自己的JNI系统中执行。问题是我们得到一个UnsupportedOperationException,“大小必须适合32位。”。这个问题在Android 1.5到2.3上似乎是一致的。我们还没有在任何Android 3设备上尝试过重新编译器。
这是其他人遇到的错误,我猜其他开发人员也做过类似的事情。
答案 0 :(得分: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调用以及传递给它的所有参数的值,则可能更容易找到原因。
答案 1 :(得分:0)
我设法找到了解决办法。当我将所有Bitmap.createBitmap调用包装在Activity.runOnUiThread()中时,它可以工作。