废话不多说!
<1> : 新建一个DurianAsJni的android工程.
<2> : 新建一个jni的java接口类:
package org.durian.durianasjni;
/**
* Project name : DurianAsJni
* Created by zhibao.liu on 2016/3/28.
* Time : 19:33
* Email warden_sprite@foxmail.com
* Action : durian
*/
public class aslib {
public native float getDurianLibVersion();
static{
System.loadLibrary("aslib");
}
}
<3> : 然后在src目录下新建一个jni目录,在jni目录下添加Android.mk和Application.mk.
<4> : 由于这里使用的是onload的方式,所以新建jni_onload.h,jni_onload.cpp
jni_onload.h
#include<jni.h>
#ifndef _ON_LOAD_HEADER_H__
#define _ON_LOAD_HEADER_H__
#ifdef __cplusplus
extern "C" {
#endif
JNIEnv* getJNIEnv();
int jniThrowException(JNIEnv *env,const char* className,const char* msg);
int jniRegisterNativeMethods(JNIEnv* env,const char* className,const JNINativeMethod* gMethod,int numMethods);
#ifdef __cplusplus
}
#endif
#endif
jni_onload.cpp
#include "jni_onload.h"
#include "durian_opencv.h"
extern int register_android_jni_durian_android(JNIEnv *env);
/*
extern int register_android_jni_durian_android_1(JNIEnv *env);
...
extern int register_android_jni_durian_android_n(JNIEnv *env);
*/
static JavaVM *sEnv;
int jniThrowException(JNIEnv *env, const char* className, const char* msg) {
jclass exceptionClass = env->FindClass(className);
if (exceptionClass == NULL) {
return -1;
}
if (env->ThrowNew(exceptionClass, msg) != JNI_OK) {
}
return 0;
}
JNIEnv* getJNIEnv() {
JNIEnv* env = NULL;
if (sEnv->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return NULL;
}
return env;
}
int jniRegisterNativeMethods(JNIEnv* env, const char* className,
const JNINativeMethod* gMethods, int numMethods) {
jclass clazz;
clazz = env->FindClass(className);
if (clazz == NULL) {
return -1;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
return -1;
}
return 0;
}
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
jint result = JNI_ERR;
sEnv = vm;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return result;
}
LOGI("JNI_OnLoad...");
/*ready to register all methods
*/
if (register_android_jni_durian_android(env) != JNI_OK) {
goto end;
}
//following could do it as the previous the way of register
/*if (register_android_jni_durian_android_1(env) != JNI_OK) {
goto end;
}
...
if (register_android_jni_durian_android_n(env) != JNI_OK) {
goto end;
}*/
return JNI_VERSION_1_4;
end: return result;
}
这两个文件都被我弄成标配文件了.
<5> : 功能源代码,在jni目录下新建durian_opencv.h和durian_opencv.cpp,代码如下:
durian_opencv.h
//
// Created by $zhibao.liu on 2016/3/28.
//
#ifndef DURIANASJNI_DURIAN_OPENCV_H
#define DURIANASJNI_DURIAN_OPENCV_H
#include<string.h>
#include<stdlib.h>
#include <android/log.h>
#include "jni_onload.h"
#define LOG_TAG "durian"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
#endif //DURIANASJNI_DURIAN_OPENCV_H
对应的durian_opencv.cpp
//
// Created by $zhibao.liu on 2016/3/28.
//
#include "durian_opencv.h"
const static char *classpath="org/durian/durianasjni/aslib";
namespace android{
float getDurianLibVersion(JNIEnv *env, jobject thiz){
return 0.5;
}
}
using namespace android;
static JNINativeMethod mMethods[] = {
{ "getDurianLibVersion", "()F",(void *) getDurianLibVersion },
};
int register_android_jni_durian_android(JNIEnv* env) {
return jniRegisterNativeMethods(env, classpath, mMethods,sizeof(mMethods) / sizeof(mMethods[0]));
}
写完c源代码后,修改Android.mk文件:
LOCAL_PATH $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := aslib
LOCAL_SRC_INCLUDE=jni_onload.cpp durian_opencv.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
<6> : NDK环境配置:
gradle.properties文件最后一行添加:
android.useDeprecatedNdk=true
local.properties文件最后一行添加NDK包的路径:
ndk.dir=D\:\\liuzhibao\\Android\\android-ndk-r10
最后再build.gradle文件中添加ndk编译:
ndk{
moduleName "aslib"
ldLibs "log", "z", "m"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
就差不多了
<7> : 在android java主程序中添加测试程序:
package org.durian.durianasjni;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private aslib mlib;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mlib=new aslib();
float ver=mlib.getDurianLibVersion();
Toast.makeText(MainActivity.this,"lib version : "+ver,Toast.LENGTH_SHORT).show();
}
}
运行,就可以获得版本号了.easy...