jni - app崩溃

时间:2012-04-27 16:16:20

标签: java android android-ndk java-native-interface

这是与NDK和Android SDK相关的问题。 目前,我的C代码正在调用Java中定义的方法。此方法称为callFromNDK()。

在这种方法中,我引用媒体播放器的一个实例来播放一个简短的测试音。 callFromNDK()每2秒调用一次。测试音调本身就是一秒钟。

我看到的是一个     (SIGSEGV),代码1(SEGV_MAPERR),故障addr fffffff4有时。

我想知道是否会发生这种情况,因为媒体播放器实例是在与其使用的上下文不同的上下文中创建的?

这是相关的代码片段[Java文件]

public class Canvastutorial extends Activity {
    private static MediaPlayer mediaPlayer = null;
    public void callFromNDK() {
        if (mediaPlayer != null) {
            mediaPlayer.start();
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.audioclip);
        mediaPlayer.setLooping(false);
    }

    @Override
    protected void onDestroy() {
        mediaPlayer.release();
        mediaPlayer = null;
        System.gc();
        super.onDestroy();
    }

    @Override
    protected void onPause() {
        stopAndPrepare();
        super.onPause();
    }   

    private void stopAndPrepare() {
            mediaPlayer.stop();
            try {
                mediaPlayer.prepare();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mediaPlayer.seekTo(0);
    }
}

当应用程序崩溃时,LogCat如下所示:

04-27 10:42:13.228: I/DEBUG(8926): Build fingerprint: 'google/passion/passion:2.3.6/GRK39F/189904:user/release-keys'
04-27 10:42:13.228: I/DEBUG(8926): pid: 10362, tid: 11222  >>> <package_name> <<<
04-27 10:42:13.228: I/DEBUG(8926): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr fffffff4
04-27 10:42:13.238: I/DEBUG(8926):  r0 4214cdc0  r1 00000000  r2 00000000  r3 0000ce68
04-27 10:42:13.238: I/DEBUG(8926):  r4 44628398  r5 00000000  r6 4472fbd8  r7 0000000e
04-27 10:42:13.238: I/DEBUG(8926):  r8 80018000  r9 00000000  10 00000000  fp 800a5368
04-27 10:42:13.238: I/DEBUG(8926):  ip 00000000  sp 4472fb88  lr 8001d084  pc 8001d090  cpsr 60000010
04-27 10:42:13.238: I/DEBUG(8926):  d0  00650072006800b8  d1  00000044bed7f457
04-27 10:42:13.238: I/DEBUG(8926):  d2  0069006400650052  d3  004d0049002e0040
04-27 10:42:13.238: I/DEBUG(8926):  d4  0061006900640065  d5  00790061006c0050
04-27 10:42:13.238: I/DEBUG(8926):  d6  0065005300720065  d7  0063006900760072
04-27 10:42:13.238: I/DEBUG(8926):  d8  0000000000000000  d9  0000000042ba56de
04-27 10:42:13.238: I/DEBUG(8926):  d10 0000000000000000  d11 0000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d12 0000000000000000  d13 0000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d14 0000000000000000  d15 0000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d16 0000000000000001  d17 c053000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d18 0000000000000000  d19 0000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d20 3ff0000000000000  d21 8000000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d22 0000000000000000  d23 ff00000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d24 ff00000000000000  d25 ff00000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d26 0100010001000100  d27 0100010001000100
04-27 10:42:13.238: I/DEBUG(8926):  d28 0100010001000100  d29 3ff0000000000000
04-27 10:42:13.238: I/DEBUG(8926):  d30 0000000000000000  d31 3ff0000000000000
04-27 10:42:13.238: I/DEBUG(8926):  scr 60000012
04-27 10:42:13.328: I/DEBUG(8926):          #00  pc 0001d090  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #01  pc 000220e4  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #02  pc 00020fdc  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #03  pc 0005fc40  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #04  pc 0004cff8  /system/lib/libdvm.so
04-27 10:42:13.328: I/DEBUG(8926):          #05  pc 00001590  /data/data/<package_name>/lib/libtest-jni.so
04-27 10:42:13.328: I/DEBUG(8926):          #06  pc 000016ca  /data/data/<package_name>/lib/libtest-jni.so
04-27 10:42:13.328: I/DEBUG(8926):          #07  pc 000118e4  /system/lib/libc.so
04-27 10:42:13.328: I/DEBUG(8926):          #08  pc 000114b0  /system/lib/libc.so
04-27 10:42:13.328: I/DEBUG(8926): code around pc:
04-27 10:42:13.328: I/DEBUG(8926): 8001d070 fa0108cc ea000017 e3a00001 e3a09000 
04-27 10:42:13.328: I/DEBUG(8926): 8001d080 ebffff72 e2450014 e5905000 e5909004 
04-27 10:42:13.328: I/DEBUG(8926): 8001d090 e515200c e5963018 e3520000 1592a000 
04-27 10:42:13.328: I/DEBUG(8926): 8001d0a0 e3a01000 0affff8a e1f970b6 e5862010 
04-27 10:42:13.328: I/DEBUG(8926): 8001d0b0 e59a1028 e5835028 e590a010 e1a04009 
04-27 10:42:13.328: I/DEBUG(8926): code around lr:
04-27 10:42:13.328: I/DEBUG(8926): 8001d064 e088f30c e1a01000 e5960018 fa0108cc 
04-27 10:42:13.328: I/DEBUG(8926): 8001d074 ea000017 e3a00001 e3a09000 ebffff72 
04-27 10:42:13.328: I/DEBUG(8926): 8001d084 e2450014 e5905000 e5909004 e515200c 
04-27 10:42:13.328: I/DEBUG(8926): 8001d094 e5963018 e3520000 1592a000 e3a01000 
04-27 10:42:13.328: I/DEBUG(8926): 8001d0a4 0affff8a e1f970b6 e5862010 e59a1028 
04-27 10:42:13.328: I/DEBUG(8926): stack:
04-27 10:42:13.328: I/DEBUG(8926):     4472fb48  4472fbe0  
04-27 10:42:13.328: I/DEBUG(8926):     4472fb4c  4214cce4  
04-27 10:42:13.328: I/DEBUG(8926):     4472fb50  0000ce60  
04-27 10:42:13.328: I/DEBUG(8926):     4472fb54  00000001  
04-27 10:42:13.328: I/DEBUG(8926):     4472fb58  4472fbe0  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb5c  80049697  /system/lib/libdvm.so
04-27 10:42:13.338: I/DEBUG(8926):     4472fb60  4214cce4  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb64  431fbec9  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb68  ad34675d  /system/lib/libandroid_runtime.so
04-27 10:42:13.338: I/DEBUG(8926):     4472fb6c  4472fbe0  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb70  42f8e91e  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb74  4214cd00  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb78  4472fbd8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb7c  40038360  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb80  df002777  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb84  e3a070ad  
04-27 10:42:13.338: I/DEBUG(8926): #00 4472fb88  4214e32c  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb8c  4472fbd8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb90  00000001  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb94  002c2c40  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb98  0000ce68  
04-27 10:42:13.338: I/DEBUG(8926):     4472fb9c  000f45b8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fba0  800aad38  
04-27 10:42:13.338: I/DEBUG(8926):     4472fba4  fffffe84  
04-27 10:42:13.338: I/DEBUG(8926):     4472fba8  800a5368  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbac  800220e8  /system/lib/libdvm.so
04-27 10:42:13.338: I/DEBUG(8926): #01 4472fbb0  4472fbd8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbb4  0000ce60  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbb8  80022058  /system/lib/libdvm.so
04-27 10:42:13.338: I/DEBUG(8926):     4472fbbc  423298c8  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbc0  00000000  
04-27 10:42:13.338: I/DEBUG(8926):     4472fbc4  80020fe0  /system/lib/libdvm.so

任何想法都表示赞赏。

感谢。

项目的本机端:定期调用thread_function get(间隔2秒),这就是我调用Java代码中定义的函数的地方。

// Callbacks to Android
JavaVM *j_vm;
jobject *j_obj;
JNIEnv *j_env;
jclass j_cls;
jmethodID android_call;

int JNI_OnLoad(JavaVM* vm, void* reserved) {
    j_vm = vm;
    (*j_vm)->GetEnv(j_vm, (void**) &j_env, JNI_VERSION_1_6);
    j_cls = (*j_env)->FindClass(j_env, "<package_name>/<class_name>");
    android_call = (*j_env)->GetMethodID(j_env, j_cls, "callFromNDK", "()V");
    j_obj = (*j_env)->NewGlobalRef(j_env, (*j_env)->NewObject(j_env, j_cls, android_call));
    return JNI_VERSION_1_6;
}

void JNI_OnUnload(JavaVM *vm, void *reserved) {
    (*j_env)->DeleteGlobalRef(j_env, j_obj);
}

void *thread_function(void *ptr) {
    int *which = (int *) ptr;
    (*j_vm)->AttachCurrentThread(j_vm, &j_env, NULL);
    int rc;
    while (!stop_thread) {
        rc = pthread_mutex_lock(&mtx);
        rc = pthread_cond_wait(&cond, &mtx);
        rc = pthread_mutex_unlock(&mtx);
        if (!stop_thread) {
            (*j_env)->CallVoidMethod(j_env, j_obj, android_call);
        }
    }
    (*j_vm)->DetachCurrentThread(j_vm);
    return NULL;
}

2 个答案:

答案 0 :(得分:0)

您是否尝试在模拟器中运行它?由于它在libdvm中崩溃,你可能会在本机崩溃之前获得一些非常有用的日志记录。

问题可能是以下几行:

j_cls = (*j_env)->FindClass(j_env, "<package_name>/<class_name>");

假设您使用实际的命名空间和类名替换"<package_name>/<class_name>"是否安全?

答案 1 :(得分:0)

通过观察,我看到此代码中有三个错误,但使用CheckJNI(http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html)运行,Dalvik应该告诉你做错了什么。 (您应该使用最新版本进行最佳检查。我注意到的一个错误将不会被Gingerbread发现[并且您将在Gingerbread中躲过它]。)

开发和调试时应始终使用CheckJNI。在发布包含单词JNI的任何问题之前,StackOverflow可能应该让人们检查“是的,我尝试过CheckJNI”框: - )