别人完整的:http://www.linuxidc.com/Linux/2014-03/97562.htm
下面会出现主线程一直在jni层 没没回到java层 , 原因在于pthread_join
1.
#include <string.h>
#include <jni.h>#include <fcntl.h>
#include <android/log.h>
#include<linux/input.h>
#include <sys/poll.h>
#include <poll.h>
#include <pthread.h>
#define LOG_MIX "gesture"
#define LOGM(...) __android_log_print(ANDROID_LOG_INFO,LOG_MIX,__VA_ARGS__)
#define LOGG(...) __android_log_print(ANDROID_LOG_ERROR,LOG_MIX,__VA_ARGS__)
//#define RF_EVENT "/sys/devices/virtual/input/input0/event0/uevent"
#define RF_EVENT "/dev/input/event0"
#define INFTIM -1
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
* apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
*/
//全局变量
JavaVM *g_jvm = NULL;
JNIEnv* jniEnv;
jobject mGestureManager;
jclass GestureManager;
jmethodID mid;
JNIEnv* zdythread;
void thread(void) {
int i;
//Attach主线程
if ((*g_jvm)->AttachCurrentThread(g_jvm, &jniEnv, NULL) != JNI_OK) {
LOGM("%s: AttachCurrentThread() failed");
return;
}
LOGM("AttachCurrentThread OK");
for (i = 0; i < 3; i++) {
LOGM("This is a pthread.\n");
(*jniEnv)->CallVoidMethod(jniEnv, mGestureManager, mid);
}
//Detach主线程
if ((*g_jvm)->DetachCurrentThread(g_jvm) != JNI_OK) {
LOGM("%s: DetachCurrentThread() failed");
}
LOGM("%s: DetachCurrentThread() OK");
//pthread_exit(0);
}
void startListener() {
pthread_t id;
int i, ret;
ret = pthread_create(&id, NULL, (void *) thread, NULL);
if (ret != 0) {
LOGM("Create pthread error!\n");
return;
}
(*jniEnv)->CallVoidMethod(jniEnv, mGestureManager, mid);
for (i = 0; i < 3; i++)
LOGM("This is the main process.\n");
pthread_join(id, NULL);
return;
}
jstring Java_com_ubtech_alpha2_jni_GestureManager_openGesture(JNIEnv* env,
jobject thiz, jobject gesture) {
jniEnv = env;
//保存全局JVM以便在子线程中使用
(*env)->GetJavaVM(env, &g_jvm);
//使用了jvm 线程则需要设置成全局变量
mGestureManager = (*env)->NewGlobalRef(env,gesture);
//1.拿到class
GestureManager = (*env)->FindClass(env,
"com/ubtech/alpha2/jni/GestureManager");
//2.拿到方法id
mid = (*env)->GetMethodID(env, GestureManager, "notityByJNI", "()V");
//3.根据obj,和方法id 调用方法
//(*jniEnv)->CallVoidMethod(jniEnv, mGestureManager, mid);
startListener();
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
2.
package com.ubtech.alpha2.jni;
import android.content.Intent;
import android.util.Log;
import com.example.voic.MainActivity;
public class GestureManager {
public static final String RF_EVENT = "/dev/input/event0";
public native static String openGesture(GestureManager mGestureManager);
//
// public native static void startListener();
//
// public native static void stopListener();
// public native static void closeGesture();
public void notityByJNI() {
// Intent intent = new Intent();
// intent.setAction("com.xiazdong");
// intent.putExtra("name", "xiazdong");
// MainActivity.mContext.sendBroadcast(intent);
Log.i("zdy", "********");
}
}
package com.example.voic;
import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import com.ubtech.alpha2.jni.GestureManager;
public class MainActivity extends ActionBarActivity {
private AudioManager mAudioManager;
static {
System.loadLibrary("gesture");
}
public static Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// addVolume();
mContext = this;
String x = GestureManager.openGesture(new GestureManager());
// TextView tv = (TextView)findViewById(R.id.zdy);
// tv.setText(x);
}
public void addVolume() {
mAudioManager = (AudioManager) this
.getSystemService(Context.AUDIO_SERVICE);
// 当前音量
int currentVolume = mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
int maxVolume = mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
currentVolume = 8;
// currentVolume = currentVolume < maxVolume ? currentVolume :
// maxVolume;
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume,
0); // tempVolume:音量绝对值
}
}