简单介绍一下步骤:首先加载本地方法,然后通过Javah 一系列命令生成C语言的 头文件 .h 文件 ;然后编写C 文件 ,在c中用到定义的本地方法 ;然后写 Android .mk 文件 控制 so文件的编译 ;编译so文件
1.创建本地方法 ,加载 so文件
public class SecretKey{
static{
System.loadLibrary(" key");// 加载动态类库 ,这里的 key 是so文件的名字
}
public static native String getKey(Object contextobject); 本地方法用 native 标识
}
这里需要 Build - > Make Project 生成class文件
2.生成 .h 文件(使用Javah命令 将上一步生成的 .class 文件生成.h 头文件)
其中.h 文件,存在 main文件夹下 jni文件夹中,如下:
在当前项目的main文件夹路径下 javah -d jni -classpath <sdk....... android.jar> ; <App_class>
App_class: 指 so 所在的 class类的文件夹 在 build\intermediates\classes\debug 包名.类名
sdk....android.jar : E:\Androidstudio\asdk\platforms\android-16\android.jar
包名类名:com.alldk.testdz.Api.SecretKey
例如:
E:\...... testDz\app\src\main>javah -d jni -classpath E:\Androidstudio\asdk\platforms\android-16\android.jar;E:\testDZ\testDz\ap
p\build\intermediates\classes\debug com.alldk.testdz.Api.SecretKey
第二步这里,尤其注意,sdk中 android.jar的路径 ,还要在<project>\app\src\main 路径下
3.对应 的 .C文件,这里以 testDz中的c文件为例子
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>com_alldk_testdz_Api_SecretKey_getSecretKey 引用本地的方法名
#include <android/log.h>
#ifndef LOG_TAG
#define LOG_TAG "ANDROID_LAB"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#endif
/* Header for class lab_sodino_jnitest_MainActivity */
#ifndef _Included_com_alldk_testdz_Api_SecretKey 这两个地方引入的是.h文件名
#define _Included_com_alldk_testdz_Api_SecretKey
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_alldk_testdz_Api_SecretKey_
* Method: getSecretKey
* Signature: ()Ljava/lang/String;
这里的参数 (JNIEnv * env ,jobject jObj)
com_alldk_testdz_Api_SecretKey_getSecretKey 这个是方法名的引用
JNIEnv * env 不用管;jobject jObj 是传递的数据
*/
JNIEXPORT jstring JNICALL Java_com_alldk_testdz_Api_SecretKey_getSecretKey
(JNIEnv * env, jobject jObj){
LOGE("log string from ndk.");
return (*env)->NewStringUTF(env,"这里是你想传递的数据");
}
#ifdef __cplusplus
}
#endif
#endif
4.创建 android.mk 文件,该文件控制so文件如何编译
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)
#bzlib 模块
bzlib_files:=\one.c
LOCAL_MODULE := libbz
LOCAL_SRC_FILES := $(bzlib_files)
include $(BUILD_STATIC_LIBRARY)
#bspath模块
include $(CLEAR_VARS)
LOCAL_MODULE := one
LOCAL_SRC_FILES := one.c
LOCAL_STATIC_LIBRARIES := libbz #引入libbz库
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := key 这里是 加载的so文件的名字
LOCAL_SRC_FILES := one.c 这里是c文件名字
LOCAL_STATIC_LIBRARIES := one
LOCAL_LDLIBS := -llog#加入log
include $(BUILD_SHARED_LIBRARY)
5.在控制台 main文件夹路径下 ndk-build 生成so文件
6.配置 build.gradle(这一步应该在前面配置)
android下 defaultConfig 下 配置ndk信息
ndk {
moduleName ' 这里的名字是 so文件的名字'
abiFilters "arm64-v8a", "armeabi", "armeabi-v7a", "mips" , "x86", "x86_64"
}
在 android下 (这个配置是在 main下面 创建 libs文件夹,通过 ndk-build后 生成的so文件在 libs文件夹下)
sourceSets{
main{
jniLibs.srcDirs=['libs']
jni.srcDirs=[ ]
}
}
as中 android视图下,在 build.gradle中配置如下代码,会生成文件夹 jniLibs目录,不需要自己去创建, 之后把生成的so文件拷贝一份放到这里。
sourceSets{
main{
jniLibs.srcDirs=['libs']
jni.srcDirs=[ ]
}
}
其中 ,在所有的步骤中 ,有三个地方都引用 so文件的名字
1. 加载so文件时
static{
System.loadLibrary("key")
}
2.在build文件中ndk的设置
ndk{
moduleName 'key'
.......
}
3.编写Android.mk文件时
LOCAL_MODULE= ' key' 与 so 文件名保持一致
最后总结生成so文件的步骤如下:
参考文章 :http://blog.youkuaiyun.com/sodino/article/details/41946607
http://www.2cto.com/kf/201608/533816.html 主要是这一篇