AndroidStudio 3.0 NDK开发1——环境搭建与编译
source link: http://www.koffuxu.com/uncategorized/781.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
前提
JNI开发主要有两种方式,一种是在Android源码中编译,另外一种是使用AndroidStuido工具开发。主要是看自己的业务场景。
如果你们公司是平台型开发方式,很容易或者当前就是在Android源码中做项目,推荐使用第一种方式,有Swig工具的加持也是效率很高;
如果公司是偏APP开发,得要适配不同平台,建议使用AndroidStudio工具来开发。本文讲这种方式。
使用AndroidStudio编译C/C++主要有两种方式:CMake和ndk-build
CMake:需要自己编写cmake.txt规则,使用CMake工具来编译;
ndk-build:需要自己编译Android.mk文件,使用ndk-build工具来编译。
因为Android源码是使用Android.mk来编译,所以我更习惯使用ndk-build这种方式。西方是讲这种方式。
Prepare
源码Android SDK快速迭代,JNI在AndroidStudio不同版本上使用有较大的区别,我这贴出我使用AndroidStudio相关版本的情况
OS Windows 10 10.0 NDK 17.2 JDK JRE: 1.8.0_152-release-915-b01 amd64 AndroidStudio IDE Android Studio 3.0Build #AI-171.4408382, built on October 21, 2017 gradlewrap 版本 gradle-4.4-all.zip AS gradle插件 com.android.tools.build:gradle:3.0.0
Starting
1,安装NDK,CMake,LLDB
2,编写并编译JAVA代码
第一步,在自己的项目中新建Java Class: MyJniTest.java
package com.aispeech.aistools.jni; /** * @Author: Gangfeng Xu([email protected]) * @Date: 9/14/2018 */ public class MyJniTest { static { System.loadLibrary("hello-jni"); } public native String getJniVersionName(); }
14
14
1
package com.aispeech.aistools.jni;
2
3
/**
4
* @Author: Gangfeng Xu([email protected])
5
* @Date: 9/14/2018
6
*/
7
8
public class MyJniTest {
9
static {
10
System.loadLibrary("hello-jni");
11
}
12
public native String getJniVersionName();
13
14
}
第二步,Ctrl + F9 make项目
第三步,在app/build目录找到这个类的class文件
第四步,生成头文件
第一种:进到debug目录,执行命令生成头文件
C:\Users\koffuxu\02-sulab\aispeech-tools\app\build\intermediates\classes\debug>javah -jni com.aispeech.aistools.jni.MyJniTest C:\Users\koffuxu\02-sulab\aispeech-tools\app\build\intermediates\classes\debug>dir Volume in drive C has no label. Volume Serial Number is 09C1-B27D Directory of C:\Users\koffuxu\02-sulab\aispeech-tools\app\build\intermediates\classes\debug 09/14/2018 05:05 PM <DIR> . 09/14/2018 05:05 PM <DIR> .. 09/14/2018 04:58 PM <DIR> android 09/14/2018 04:58 PM <DIR> androidx 09/14/2018 04:58 PM <DIR> com 09/14/2018 05:05 PM 567 com_aispeech_aistools_jni_MyJniTest.h 1 File(s) 567 bytes 5 Dir(s) 173,480,382,464 bytes free
16
16
1
C:\Users\koffuxu\02-sulab\aispeech-tools\app\build\intermediates\classes\debug>javah -jni com.aispeech.aistools.jni.MyJniTest
2
3
C:\Users\koffuxu\02-sulab\aispeech-tools\app\build\intermediates\classes\debug>dir
4
Volume in drive C has no label.
5
Volume Serial Number is 09C1-B27D
6
7
Directory of C:\Users\koffuxu\02-sulab\aispeech-tools\app\build\intermediates\classes\debug
8
9
09/14/2018 05:05 PM <DIR> .
10
09/14/2018 05:05 PM <DIR> ..
11
09/14/2018 04:58 PM <DIR> android
12
09/14/2018 04:58 PM <DIR> androidx
13
09/14/2018 04:58 PM <DIR> com
14
09/14/2018 05:05 PM 567 com_aispeech_aistools_jni_MyJniTest.h
15
1 File(s) 567 bytes
16
5 Dir(s) 173,480,382,464 bytes free
第二种方法:进入需要创建的模块main下面,其实是一样的,只是这种方法看起来更合规,并且省掉了第五步
C:\Users\koffuxu\02-sulab\aispeech-tools\usbrcvoicelib\src\main>javah -d jni -classpath C:\Users\koffuxu\02-sulab\aispeech-tools\usbrcvoicelib\build\intermediates\classes\debug com.aispeech.usbrcvoicelib.nativeutils.UsbVoiceManager
x
1
C:\Users\koffuxu\02-sulab\aispeech-tools\usbrcvoicelib\src\main>javah -d jni -classpath C:\Users\koffuxu\02-sulab\aispeech-tools\usbrcvoicelib\build\intermediates\classes\debug com.aispeech.usbrcvoicelib.nativeutils.UsbVoiceManager
第五步,创建JNI文件夹,位于java的同级目录
第六步,把第四步生成的.h文件copy到这个文件夹,同时创建my_jni_test.c文件和Android文件
内容如下:
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni #指定了生成的动态链接库的名字 LOCAL_SRC_FILES := my_jni_test.c #指定了C的源文件叫什么名字 include $(BUILD_SHARED_LIBRARY) # 制定要生成动态链接库
6
1
LOCAL_PATH := $(call my-dir)
2
include $(CLEAR_VARS)
3
LOCAL_MODULE := hello-jni #指定了生成的动态链接库的名字
4
LOCAL_SRC_FILES := my_jni_test.c #指定了C的源文件叫什么名字
5
6
include $(BUILD_SHARED_LIBRARY) # 制定要生成动态链接库
my_jni_test.c
#include "com_aispeech_aistools_jni_MyJniTest.h" JNIEXPORT jstring JNICALL Java_com_aispeech_aistools_jni_MyJniTest_getJniVersionName (JNIEnv * env, jobject obj) { return (*env)->NewStringUTF(env, "Hello , I'm from JNI"); }
5
5
1
#include "com_aispeech_aistools_jni_MyJniTest.h"
2
JNIEXPORT jstring JNICALL Java_com_aispeech_aistools_jni_MyJniTest_getJniVersionName
3
(JNIEnv * env, jobject obj) {
4
return (*env)->NewStringUTF(env, "Hello , I'm from JNI");
5
}
第七步,添加编译项目
在app下面的build.gradule添加
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } externalNativeBuild { ndkBuild { path 'src/main/jni/Android.mk' } }
11
11
1
buildTypes {
2
release {
3
minifyEnabled false
4
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
5
}
6
}
7
externalNativeBuild {
8
ndkBuild {
9
path 'src/main/jni/Android.mk'
10
}
11
}
或者通过IDE添加
第八步,编译完成,将看到不同平台的so文件
第九步,验证
在MainActivity.java里面调MyJniTest的方法,编译,安装验证
Log.e(TAG, "initDate: Jni version="+new MyJniTest().getJniVersionName());
1
1
Log.e(TAG, "initDate: Jni version="+new MyJniTest().getJniVersionName());
打印查看
多平台支持
如果需要支持更多平台,比如Mips,需要在jni的目录添加Application.mk添加相差参数
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK