Android 从本机调用复制位图
我有一个从本机c代码调用的Java方法。它的工作很简单,复制一个位图。但它使它毫无差错地爆炸了Android 从本机调用复制位图,android,android-ndk,java-native-interface,Android,Android Ndk,Java Native Interface,我有一个从本机c代码调用的Java方法。它的工作很简单,复制一个位图。但它使它毫无差错地爆炸了 public synchronized Bitmap copyScreen() { try { Log.d(TAG, "before copy Screen"); //Any of these lines make it bomb out. // Bitmap copy = bmp.copy(bmp.getCo
public synchronized Bitmap copyScreen() {
try {
Log.d(TAG, "before copy Screen");
//Any of these lines make it bomb out.
// Bitmap copy = bmp.copy(bmp.getConfig(), false);
//Bitmap copy = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(),
// bmp.getConfig());
Bitmap copy = Bitmap.createBitmap(800, 480, Config.ARGB_8888);
Log.d(TAG, "after copy Screen");
return copy;
} catch (Exception ex) {
Log.e(TAG, "copyScreen", ex);
return null;
}
}
我可以毫无问题地从Java调用这个copyScreen
。只有当它从JNI调用时,它才会爆炸
如果我不做任何复制行,它也可以正常工作
日志只显示:
11-15 20:10:49.234:D/图形缓冲(24341):复制屏幕前
注意,本机代码在与主线程分离的线程中运行。我已同步对bmp
字段的所有访问。但是,即使制作一个新的位图,也会导致它退出。如果位图很小,就可以了
Bitmap copy = Bitmap.createBitmap(80, 48, Config.ARGB_8888);
工作正常,那么我可以从JNI分配的资源是否有一些限制?我很确定我的问题在于我对java环境的引用方式: 我的旧main和getJNIEnv
JNIEnv *_env;
JNIEXPORT void JNICALL Java_com_comp_prod_main(JNIEnv *env,
jclass thiz) {
LOGV("Main called %d", __LINE__);
_env = (JNIEnv *) ((*env)->NewGlobalRef(env, env));
main(); //somewhere in here it calls back to the java which creates the bitmap
_env = NULL;
}
JNIEnv *getJNIEnv(void) {
return _env;
}
JavaVM *jvm;
JNIEXPORT void JNICALL Java_com_comp_prod_main(JNIEnv *env,
jclass thiz) {
LOGV("Main called %d", __LINE__);
//this is how to cache it for other threads
jint rs = (*env)->GetJavaVM(env, &jvm);
assert (rs == JNI_OK);
main(); //somewhere in here it calls back to the java which creates the bitmap
jvm = NULL;
}
JNIEnv *getJNIEnv(void) {
JNIEnv *env;
jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
assert (rs == JNI_OK);
if(env == NULL)
{
LOGV("env is NULL");
}
return env;
}
我的新main和getJNIEnv
JNIEnv *_env;
JNIEXPORT void JNICALL Java_com_comp_prod_main(JNIEnv *env,
jclass thiz) {
LOGV("Main called %d", __LINE__);
_env = (JNIEnv *) ((*env)->NewGlobalRef(env, env));
main(); //somewhere in here it calls back to the java which creates the bitmap
_env = NULL;
}
JNIEnv *getJNIEnv(void) {
return _env;
}
JavaVM *jvm;
JNIEXPORT void JNICALL Java_com_comp_prod_main(JNIEnv *env,
jclass thiz) {
LOGV("Main called %d", __LINE__);
//this is how to cache it for other threads
jint rs = (*env)->GetJavaVM(env, &jvm);
assert (rs == JNI_OK);
main(); //somewhere in here it calls back to the java which creates the bitmap
jvm = NULL;
}
JNIEnv *getJNIEnv(void) {
JNIEnv *env;
jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
assert (rs == JNI_OK);
if(env == NULL)
{
LOGV("env is NULL");
}
return env;
}
仅供参考,所有的c都是单线程的,但是以独立的线程运行到主线程。这是如何从Java开始的:
Runnable runTerm = new Runnable() {
public void run() {
// call main()
Log.i(TAG, "About to call main on the c!");
try {
Terminal.main();
} catch (IOException e) {
e.printStackTrace();
}
}
};
t = new Thread(runTerm, "C thread");
t.start();
logcat炸弹输出是什么?位图仍将在Java堆中分配。你说的炸弹是什么意思?什么都没发生,应用程序崩溃,一定是出了什么问题或者至少是出了什么问题。。。尝试制作一个独立的应用程序来重现错误并发布JNI代码。@auselen这是我的想法。日志猫显示Zillch,只是我的日志消息和一般系统的东西。我会尝试制作一个小的复制应用程序。@auselen是的,它是wierd,没有seg故障或任何东西。我想我在解决另一个问题时已经破解了它。