如果从onclick事件ndk函数调用,为什么应用程序崩溃:
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()
{
}
}
日志:
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/DEBUG(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
答案 0 :(得分:2)
问题是您的本机方法声明了无效的signautre, 然后你尝试缓存本地引用。 方法签名规则很难记住,我们通常通过javah工具生成它。
Javah易于使用。创建项目后,您可以使用bin文件夹中的内置.class:
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
添加-jni选项以生成C标头:
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_
最后,您获得了正确的方法签名:
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
如果您想了解更多有关jni的信息,请阅读一本好书: Java Native Interface:程序员指南和规范 http://java.sun.com/docs/books/jni/
请参阅
答案 1 :(得分:0)
OnButton应如下所示:
extern "C" void Java_com_test_TestActivity_OnButton(JNIEnv *env, jobject obj)
每个 Java可调用的本机方法都应该具有这两个参数。崩溃来自于无法找到具有此类签名的名为OnButton()的本机方法。