NDK开发汇总
使用so库和头文件开发
gradle指定开发平台,在defaultConfig目录里面
ndk {
abiFilters “armeabi”,“x86”
}
引入第三方库,在app.gralde中的android目录下
sourceSets.main {
jniLibs.srcDirs = [‘libs’]
jni.srcDirs = []
}
C++中找不到外部函数,需要在头文件前加extern “C” {}
#include
#include
#include
//#include
#include
#include
//int __android_log_print(int prio, const char* tag, const char* fmt, ...)
#define TAG "Tim_JNI"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
JavaVM* g_jvm = NULL;
jobject g_obj = NULL;
/*
* Class: com_dn_tim_dn_lsn_9_FileUtils
* Method: diff
* Signature: (Ljava/lang/String;Ljava/lang/String;I)V
*/
//int addTest(int a, int b) {
// LOGI("这是第三方so库调用测试 %d,%d",a,b);
// return a+b;
//}
void* thread_fun(void * arg) {
JNIEnv *env;
jclass cls;
jmethodID mid,mid1;
if ( (*g_jvm) -> AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK ) {
LOGI("%s AttachCurrentThread error failed ",__FUNCTION__);
return NULL;
}
cls = (*env) -> GetObjectClass(env ,g_obj);
if (cls == NULL) {
LOGI("findClass error....");
goto error;
}
LOGI("call back begin");
mid = (*env) -> GetStaticMethodID(env, cls, "formJni", "(I)V");
if (mid == NULL) {
LOGI("GetStaticMethodID error....");
goto error;
}
(*env) -> CallStaticVoidMethod(env, cls, mid, (int)arg);
mid1 = (*env) -> GetMethodID(env, cls, "form_JNI_Again", "(I)V");
if (mid1 == NULL) {
LOGI("GetMethodID error....");
goto error;
}
(*env) ->CallVoidMethod(env, g_obj, mid1 ,(int)arg);
error:
if ((*g_jvm) -> DetachCurrentThread(g_jvm) != JNI_OK) {
LOGI("%s DetachCurrentThread error failed ",__FUNCTION__);
}
pthread_exit(0);
}
JNIEXPORT void JNICALL native_newThead
(JNIEnv *env, jclass clazz)
{
LOGI("newThread begin");
int i;
pthread_t pt[5];
for (i = 0; i < 5; i++) {
pthread_create(&pt[i], NULL, &thread_fun, (void*)i);
}
}
JNIEXPORT void JNICALL native_setJniEnv
(JNIEnv *env, jobject obj)
{
LOGI("native_setJniEnv");
//保存JVM
(*env) -> GetJavaVM(env, &g_jvm);
//保持actvity对象
g_obj = (*env) -> NewGlobalRef(env, obj);
}
static const JNINativeMethod gMethods_MainActivity[] = {
{
"newJniThread","()V",(void*)native_newThead
},
{
"setJniEnv", "()V",(void*)native_setJniEnv
}
};
//注册mainactivity中的native方法
static int registerNatives_Main(JNIEnv* engv)
{
LOGI("registerNatives_Main begin");
jclass clazz;
clazz = (*engv) -> FindClass(engv, "com/dn/tim/dn_lsn_9/MainActivity");
if (clazz == NULL) {
LOGI("clazz is null");
return JNI_FALSE;
}
if ((*engv) ->RegisterNatives(engv, clazz, gMethods_MainActivity, NELEM(gMethods_MainActivity)) < 0) {
LOGI("registerNatives_Main error");
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
LOGI("jni_OnLoad begin");
JNIEnv* env = NULL;
jint result = -1;
if ((*vm)->GetEnv(vm,(void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGI("ERROR: GetEnv failed\n");
return -1;
}
assert(env != NULL);
registerNatives_Main(env);
return JNI_VERSION_1_4;
}