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.
精彩评论