开发者

Android crash on call GetMethodID

Why the application crash, if you call from the onclick event ndk function:

Test.cpp

#include <jni.h>
#include <stdio.h>
#include <android/log.h>
#define  LOG_TAG    "Test"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

static JNIEnv *m_env = 0;
static jclass m_activityClass;

// Library init
extern "C" jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
    return JNI_VERSION_1_4;
}

extern "C" void Java_com_test_TestActivity_Init(JNIEnv *env, jobject obj)
{

    m_env = env;
    m_activityClass = env->GetObjectClass(obj);
}

extern "C" void Java_com_test_TestActivity_OnButton()
{
    jmethodID mId = m_env->GetMethodID(m_activityClass, "GetDeviceId", "()V");
    if (mId)
        LOGI("success");
}

TestActivity.java

package com.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class TestActivity extends Activity
{
static
{
    System.loadLibrary("Test");
}   

public native void Init();
public native void OnButton();

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Init();

    Button button = (Button)findViewById(R.id.button1);
    button.setOnClickListener(_clickListener);
}

private OnClickListener _clickListener = new OnClickListener()
{
    public void onClick(View v)
    {
        OnButton();
    }
};

public void GetDeviceId()
{

}   
}

Log:

09-03 15:08:42.719: INFO/System.out(749): debugger has settled (1480)
09-03 15:08:43.129: DEBUG/dalvikvm(749): Trying to load lib /data/data/com.test/lib/libTest.so 0x44edee48
09-03 15:08:43.129: DEBUG/dalvikvm(749): Added shared lib /data/data/com.test/lib/libTest.so 0x44edee48
09-03 15:08:43.539: WARN/InputManagerService(59): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@4504ae08 (uid=10031 pid=713)
09-03 15:08:43.689: INFO/ActivityManager(59): Displayed activity com.test/.TestActivity: 3971 ms (total 3971 ms)
09-03 15:08:48.879: DEBUG/dalvikvm(263): GC_EXPLICIT freed 50 objects / 2360 bytes in 118ms
09-03 15:08:50.189: WARN/dalvikvm(749): JNI WARNING: 0x44ee2c80 is not a valid JNI reference
09-03 15:08:50.189: WARN/dalvikvm(749):              in Lcom/test/TestActivity;.OnButton ()V (GetMethodID)
09-03 15:08:50.189: INFO/dalvikvm(749): "main" prio=5 tid=1 RUNNABLE
09-03 15:08:50.189: INFO/dalvikvm(749):   | group="main" sCount=0 dsCount=0 s=N obj=0x4001d8e0 self=0xccb0
09-03 15:08:50.199: INFO/dalvikvm(749):   | sysTid=749 nice=0 sched=0/0 cgrp=default handle=-1345026008
09-03 15:08:50.199: INFO/dalvikvm(749):   | schedstat=( 805400585 705858293 113 )
09-03 15:08:50.199: INFO/dalvikvm(749):   at com.test.TestActivity.OnButton(Native Method)
09-03 15:08:50.199: INFO/dalvikvm(749):   at com.test.TestActivity$1.onClick(TestActivity.java:36)
09-03 15:08:50.199: INFO/dalvikvm(749):   at android.view.View.performClick(View.java:2408)
09-03 15:08:50.199: INFO/dalvikvm(749):   at android.view.View$PerformClick.run(View.java:8816)
09-03 15:08:50.199: INFO/dalvikvm(749):   at android.os.Handler.handleCallback(Handler.java:587)
09-03 15:08:50.199: INFO/dalvikvm(749):   at android.os.Handler.dispatchMessage(Handler.java:92)
09-03 15:08:50.199: INFO/dalvikvm(749):   at android.os.Looper.loop(Looper.java:123)
09-03 15:08:50.199: INFO/dalvikvm(749):   at android.app.ActivityThread.main(ActivityThread.java:4627)
09-03 15:08:50.199: INFO/dalvikvm(749):   at java.lang.reflect.Method.invokeNative(Native Method)
09-03 15:08:50.199: INFO/dalvikvm(749):   at java.lang.reflect.Method.invoke(Method.java:521)
09-03 15:08:50.209: INFO/dalvikvm(749):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
09-03 15:08:50.209: INFO/dalvikvm(749):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
09-03 15:08:50.209: INFO/dalvikvm(749):   at dalvik.system.NativeStart.main(Native Method)
09-03 15:08:50.219: ERROR/dalvikvm(749): VM aborting
09-03 15:08:50.383: INFO/DEBUG(31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
09-03 15:08:50.383: INFO/DEBUG(31): Build fingerprint: 'generic/sdk/generic/:2.2/FRF91/43546:eng/test-keys'
09-03 15:08:50.389: INFO/DEBUG(31): pid: 749, tid: 749  >>> com.test <<<
09-03 15:08:50.389: INFO/DEBUG(31): signal 11 (SIGSEGV), fault addr deadd00d
09-03 15:08:50.389: INFO/DEBUG(31):  r0 00000374  r1 0000000c  r2 0000000c  r3 deadd00d
09-03 15:08:50.389: INFO/DEBUG(31):  r4 00000026  r5 80887fc4  r6 8086d834  r7 0000aa50
09-03 15:08:50.389: INFO/DEBUG(31):  r8 bea64878  r9 4186bdd4  10 0000ce04  fp 4186bdd0
09-03 15:08:50.403: INFO/DEBUG(31):  ip 808881ec  sp bea647d8  lr afd154c5  pc 8083b162  cpsr 20000030
09-03 15:08:50.489: INFO/DEBUG(31):          #00  pc 0003b162  /system/lib/libdvm.so
09-03 15:08:50.489: INFO/DEBUG(31):          #01  pc 0002cff4  /system/lib/libdvm.so
09-03 15:08:50.489: INFO/DEBUG(31):          #02  pc 0002df74  /system/lib/libdvm.so
09-03 15:08:50.489: INFO/DEBUG(31):          #03  pc 0002dfa6  /system/lib/libdvm.so
09-03 15:08:50.499: INFO/DEBUG(31):          #04  pc 0003055c  /system/lib/libdvm.so
09-03 15:08:50.499: INFO/DEBUG(31):          #05  pc 00031d54  /system/lib/libdvm.so
09-03 15:08:50.499: INFO/DEBUG(31):          #06  pc 00000ce8  /data/data/com.test/lib/libTest.so
09-03 15:08:50.509: INFO/DEBUG(31):          #07  pc 00013974  /system/lib/libdvm.so
09-03 15:08:50.509: INFO/DEBUG(31):          #08  pc 0003ddf0  /system/lib/libdvm.so
09-03 15:08:50.509: INFO/DEBUG(31):          #09  pc 000371b6  /system/lib/libdvm.so
09-03 15:08:50.529: INFO/DEBUG(31):          #10  pc 000432ec  /system/lib/libdvm.so
09-03 15:08:50.529: INFO/DEBUG(31):          #11  pc 00024dcc  /system/lib/libdvm.so
09-03 15:08:50.529: INFO/DEBUG(31):          #12  pc 0001d7cc  /system/lib/libdvm.so
09-03 15:08:50.529: INFO/DEBUG(31):          #13  pc 0005408e  /system/lib/libdvm.so
09-03 15:08:50.539: INFO/DEBUG(31):          #14  pc 0005bde2  /system/lib/libdvm.so
09-03 15:08:50.539: INFO/DEBUG(31):          #15  pc 00018714  /system/lib/libdvm.so
09-03 15:08:50.550: INFO/DEBUG(31):          #16  pc 0001e8c4  /system/lib/libdvm.so
09-03 15:08:50.550: INFO/DEBUG(31):          #17  pc 0001d790  /system/lib/libdvm.so
09-03 15:08:50.559: INFO/DEBUG(31):          #18  pc 00053eec  /system/lib/libdvm.so
09-03 15:08:50.559: INFO/DEBUG(31):          #19  pc 0004072c  /system/lib/libdvm.so
09-03 15:08:50.559: INFO/DEBUG(31):          #20  pc 00034454  /system/lib/libdvm.so
09-03 15:08:50.569: INFO/DEBUG(31):          #21  pc 0002c930  /system/lib/libandroid_runtime.so
09-03 15:08:50.579: INFO/DEBUG(31):          #22  pc 0002d85c  /system/lib/libandroid_runtime.so
09-03 15:08:50.579: INFO/DEBUG(31):          #23  pc 00008c86  /system/bin/app_process
09-03 15:08:50.579: INFO/DEBUG(31):          #24  pc 0000d362  /system/lib/libc.so
09-03 15:08:50.579: INFO/DEBUG(31): code around pc:
09-03 15:08:50.589: INFO/DEBUG(31): 8083b140 1861447c 200618a2 e878f7d8 f7d82000 
09-03 15:08:50.589: INFO/DEBUG(31): 8083b150 4808e9e4 6bdb5823 d0002b00 4b064798 
09-03 15:08:50.589: INFO/DEBUG(31): 8083b160 701c2426 ea5cf7d8 0004ce80 fffe4ae0 
09-03 15:08:50.589: INFO/DEBUG(31): 8083b170 fffe801c 00000374 deadd00d b510b40e 
09-03 15:08:50.589: INFO/DEBUG(31): 8083b180 4c0a4b09 447bb083 aa05591b 6b5bca02 
09-03 15:08:50.589: INFO/DE开发者_StackOverflowBUG(31): code around lr:
09-03 15:08:50.589: INFO/DEBUG(31): afd154a4 b0834a0d 589c447b 26009001 686768a5 
09-03 15:08:50.589: INFO/DEBUG(31): afd154b4 220ce008 2b005eab 1c28d003 47889901 
09-03 15:08:50.599: INFO/DEBUG(31): afd154c4 35544306 d5f43f01 2c006824 b003d1ee 
09-03 15:08:50.599: INFO/DEBUG(31): afd154d4 bdf01c30 0002ae7c 000000d4 1c0fb5f0 
09-03 15:08:50.599: INFO/DEBUG(31): afd154e4 43551c3d a904b087 1c16ac01 604d9004 
09-03 15:08:50.599: INFO/DEBUG(31): stack:
09-03 15:08:50.599: INFO/DEBUG(31):     bea64798  00000015  
09-03 15:08:50.599: INFO/DEBUG(31):     bea6479c  afd1453b  /system/lib/libc.so
09-03 15:08:50.609: INFO/DEBUG(31):     bea647a0  afd405a0  /system/lib/libc.so
09-03 15:08:50.609: INFO/DEBUG(31):     bea647a4  afd4054c  /system/lib/libc.so
09-03 15:08:50.609: INFO/DEBUG(31):     bea647a8  00000000  
09-03 15:08:50.609: INFO/DEBUG(31):     bea647ac  afd154c5  /system/lib/libc.so
09-03 15:08:50.609: INFO/DEBUG(31):     bea647b0  0000ccb0  [heap]
09-03 15:08:50.609: INFO/DEBUG(31):     bea647b4  afd1450d  /system/lib/libc.so
09-03 15:08:50.609: INFO/DEBUG(31):     bea647b8  0000aa50  [heap]
09-03 15:08:50.609: INFO/DEBUG(31):     bea647bc  80887fc4  /system/lib/libdvm.so
09-03 15:08:50.609: INFO/DEBUG(31):     bea647c0  80887fc4  /system/lib/libdvm.so
09-03 15:08:50.609: INFO/DEBUG(31):     bea647c4  8086d834  /system/lib/libdvm.so
09-03 15:08:50.609: INFO/DEBUG(31):     bea647c8  0000aa50  [heap]
09-03 15:08:50.609: INFO/DEBUG(31):     bea647cc  afd1456b  /system/lib/libc.so
09-03 15:08:50.609: INFO/DEBUG(31):     bea647d0  df002777  
09-03 15:08:50.619: INFO/DEBUG(31):     bea647d4  e3a070ad  
09-03 15:08:50.619: INFO/DEBUG(31): #00 bea647d8  44ee2c80  /dev/ashmem/mspace/dalvik-heap/2 (deleted)
09-03 15:08:50.619: INFO/DEBUG(31):     bea647dc  8082cff9  /system/lib/libdvm.so
09-03 15:08:50.619: INFO/DEBUG(31): #01 bea647e0  44ee2c80  /dev/ashmem/mspace/dalvik-heap/2 (deleted)
09-03 15:08:50.629: INFO/DEBUG(31):     bea647e4  8082df79  /system/lib/libdvm.so
09-03 15:08:51.209: DEBUG/Zygote(33): Process 749 terminated by signal (11)
09-03 15:08:51.221: INFO/WindowManager(59): WIN DEATH: Window{44ff35b8 com.test/com.test.TestActivity paused=false}
09-03 15:08:51.221: INFO/ActivityManager(59): Process com.test (pid 749) has died.
09-03 15:08:51.269: INFO/UsageStats(59): Unexpected resume of com.android.term while already resumed in com.test
09-03 15:08:51.280: INFO/BootReceiver(59): Copying /data/tombstones/tombstone_00 to DropBox (SYSTEM_TOMBSTONE)
09-03 15:08:51.499: DEBUG/dalvikvm(59): GC_FOR_MALLOC freed 2633 objects / 346848 bytes in 192ms
09-03 15:08:51.499: WARN/InputManagerService(59): Got RemoteException sending setActive(false) notification to pid 749 uid 10037
09-03 15:08:56.990: DEBUG/dalvikvm(220): GC_EXPLICIT freed 152 objects / 10888 bytes in 142ms


The problem is your native method declared the invalid signautre, then you try to cache the local reference. The method signature rule is hard to remember, we usually generate it by javah tool.

Javah is simple to use. After the project created, you can use the built .class in bin folder:

qrtt1:jni apple$ cd /Users/apple/Documents/workspace/TestAndroid
qrtt1:TestAndroid apple$ ls AndroidManifest.xml assets             
bin                 default.properties  gen                 res       
src qrtt1:TestAndroid apple$ cd bin

Add the -jni option to generate the C Header:

qrtt1:bin apple$ javah -jni com.test.TestActivity
qrtt1:bin apple$ ls -alh
total 72
drwxr-xr-x   8 apple  staff   272B  9  5 09:34 .
drwxr-xr-x  11 apple  staff   374B  9  5 09:28 ..
-rw-r--r--   1 apple  staff    14K  9  5 09:33 TestAndroid.apk
drwxr-xr-x   3 apple  staff   102B  9  5 09:28 aaa
-rw-r--r--   1 apple  staff   2.9K  9  5 09:33 classes.dex
drwxr-xr-x   3 apple  staff   102B  9  5 09:28 com
-rw-r--r--   1 apple  staff   597B  9  5 09:34 com_test_TestActivity.h
-rw-r--r--   1 apple  staff    10K  9  5 09:33 resources.ap_

Finally, you get the right method signature:

qrtt1:bin apple$ cat com_test_TestActivity.h 
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_test_TestActivity */

#ifndef _Included_com_test_TestActivity
#define _Included_com_test_TestActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_test_TestActivity
 * Method:    Init
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_test_TestActivity_Init
  (JNIEnv *, jobject);

/*
 * Class:     com_test_TestActivity
 * Method:    OnButton
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_test_TestActivity_OnButton
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

If you want to understand more about jni, there is a good book: Java Native Interface: Programmer's Guide and Specification http://java.sun.com/docs/books/jni/

Please see

  • Local and Global References http://java.sun.com/docs/books/jni/html/refs.html#27423
  • The Invocation Interface http://java.sun.com/docs/books/jni/html/invoke.html#11202
  • Traps and Pitfalls http://java.sun.com/docs/books/jni/html/pitfalls.html#25706


The OnButton should look like this:

extern "C" void Java_com_test_TestActivity_OnButton(JNIEnv *env, jobject obj) 

Every Java-callable native method should have these two parameters. The crash comes from the inability to find a native method called OnButton() with such a signature.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜