2

これは、NDK と Android SDK に関する質問です。現在、私の C コードは Java で定義されたメソッドを呼び出しています。このメソッドは callFromNDK() と呼ばれます。

このメソッド内で、メディアプレーヤーのインスタンスを参照して、短いテスト トーンを再生しています。callFromNDK() get は 2 秒ごとに呼び出されます。そしてテストトーン自体は1秒です。

私が見ているのは、(SIGSEGV)、コード 1 (SEGV_MAPERR)、時々障害アドレス fffffff4 です。

mediaplayer インスタンスが、それが使用されているものとは異なるコンテキストで作成されたために、これが起こっているのではないかと思いますか?

関連するコードは次のとおりです[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;
}
4

2 に答える 2

0

エミュレータで実行してみましたか?libdvm でクラッシュしたため、ネイティブ クラッシュの直前に非常に役立つログが得られるでしょう。

問題は次の行である可能性があります。

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

"<package_name>/<class_name>"実際の名前空間とクラス名に置き換えたと仮定しても安全ですか?

于 2012-04-28T21:08:59.960 に答える
0

目で見ると、このコードには 3 つのエラーが表示されますが、CheckJNI (http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html) で実行すると、Dalvik はあなたに何を伝えますか?間違ったことをした。(最適なチェックを行うには、最新のリリースで実行する必要があります。私が気付いた間違いの 1 つは、Gingerbread では検出されません [そして、Gingerbread でもそれを回避できます]。)

開発およびデバッグ中は常に CheckJNI を使用する必要があります。StackOverflow はおそらく、JNI という単語を含む質問を投稿する前に、人々に「はい、CheckJNI を試しました」ボックスをチェックさせるべきです :-)

于 2012-04-30T13:58:27.723 に答える