生成so文件

配置NDK环境变量

找到Android Studio安装的NDK包的文件目录(E:AndroidStudioSDKSDKndk-bundle),添加到系统的环境变量中

新建mk文件

在jni目录下新建Android.mk

1
2
3
4
5
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JNISample
LOCAL_SRC_FILES := com_lilei_testjni_JniUtils.cpp
include $(BUILD_SHARED_LIBRARY)

在jni目录下新建Application.mk文件

1
2
3
4
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions -std=c++0x
APP_ABI := armeabi-v7a
APP_PLATFORM := android-18

编译生成so

打开终端cd到jni目录下
调用ndk-build开始编译so

1
ndk-build

运行成功之后即会看到main文件夹下多了libs和obj的文件夹,里面就是生成的各种CPU的so文件

jni

环境配置

主要需要配置的就是NDK(Native Development Kit),现在Android studio很便利,可以一键下载: file → setting → 按截图找到如下路径 → 选择NDK → 确定应用下载

设置项目支持JNI

打开gradle.properties,添加:

1
android.useDeprecatedNdk=true

打开local.properties,添加:

1
ndk.dir=NDK的路径

最后打开app内build.gradle,在android/defaultConfig下面添加ndk配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.lilei.testjni"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
moduleName "JNISample"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

新建java访问c层的接口类

创建一个Jni的工具类,并定义接口函数,函数关键字用native(static用不用均可)

1
2
3
4
5
6
7
package com.lilei.testjni;
/**
* Created by lilei on 2017/3/29.
*/
public class JniUtils {
public static native String getJniString();
}

生成头文件

打开终端,运行

1
2
cd app/build/intermediates/classes/debug/
javah com.lilei.testjni.JniUtils

运行成功之后打开app/build/intermediates/classes/debug/ 即可找到编译出的头文件”com_lilei_testjni_JniUtils.h”,不难发现头文件名是有原报名+类名组成

创建jni开发的文件夹

点击app文件夹,New → Folder → JNI Folder, 选择在main文件夹下即可,生成成功后main目录下会出现一个jni的文件夹
找到刚才生成到头文件,复制到jni文件夹下(记得关闭刚才使用的终端,否则无法复制)
头文件有了,现在在jni目录下创建一个C++文件用于开发使用,命名与头文件相同
编写C++文件中定义函数的代码

1
2
3
4
5
6
#include "com_lilei_testjni_JniUtils.h"
JNIEXPORT jstring JNICALL Java_com_lilei_testjni_JniUtils_getJniString
(JNIEnv *env, jclass) {
// new 一个字符串,返回Hello World
return env -> NewStringUTF("Hello World");
}

java层加载so

回到JniUtils,加上

1
2
3
static {
System.loadLibrary("JNISample");
}

运行Run

调用jni的函数

1
2
3
4
5
6
7
8
9
10
11
12
package com.lilei.testjni;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("Jni", JniUtils.getJniString());
}
}

至此就成功运行出jni的Hello World了