1.什么是NDK、JNI?
NDK全稱是Native Development Kit,NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,并能自動將so和java應用一起打包成apk, NDK 是屬于 Android 的,與 Java 無直接關系,
JNI全稱為:Java Native Interface,JNI是本地編程介面,它使得在 Java 虛擬機內部運行的 Java代碼能夠與用其它語言(如 C、C++)撰寫的代碼進行互動,JNI 是屬于 Java 的,與 Android 無直接關系,
總結:JNI 是實作的目的,NDK 是 Android 中實作 JNI 的手段,JNI和NDK用來快速呼叫C/C++的動態庫,
2. NDK下載
兩種下載方式,手動下載,IDE中直接下載
- 從官網下載傳送門,下載后解壓到一個不含中文的目錄下,
- AS中下載安裝

點擊SDK Manager,切換到SDK Tools 選單

選擇一個版本下載即可,
3.AS關聯NDK

點擊Project Structure

把電腦上NDK的路徑填到這里即可,
還有一種方式關聯NDK,找到local.properties,直接把路徑填到里面,這兩種方式作用相同,

4.JNI 開發流程
4.1新建一個JNI java檔案,用來宣告native方法

package com.example.ndk;
/**
* @author : 鑫宇
* e-mail : 1769314609@qq.com
* time : 2020/11/22
* desc :
* version: 1.0
*/
public class JNI {
{
// 在JNI這個類加載的時候就去加載.so庫,生成的.so庫名字會自動加上lib前綴,我們寫的時候不要把lib前綴加上,libHello.so在后面使用cmake進行生成,
System.loadLibrary("Hello");
}
/* *
* 定義native方法,只做宣告,在C中實作,
*/
public native String sayHello();
}
4.2 編輯C檔案實作本地代碼
JNI本地介面函式名的命名規則為Java_全類名_函式名,將游標放到sayHello方法名上,注意是方法名上,右鍵選擇Copy Reference ,拿到方法的參考com.example.ndk.JNI#sayHello,然后將.和#全部換成_即可,

//
// Created by 鑫宇 on 2020/11/22.
//
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
/*
* jstring: 回傳值
* Java_全類名_方法名
* jobject: 呼叫該方法的實體
*/
jstring Java_com_example_ndk_JNI_sayHello(JNIEnv *env, jobject jobj) {
char *text = "HelloWorld";
return (*env)->NewStringUTF(env, text);
}
4.3cmake 編譯生成.so庫
首先在build.grandle中添加cmake屬性

android {
compileSdkVersion 30
buildToolsVersion "30.0.1"
defaultConfig {
applicationId "com.example.ndk"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
// 指定編譯架構
abiFilters 'arm64-v8a','armeabi-v7a','x86','x86_64'
}
}}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// 在android節點下,指定CMakeLists.txt路徑
externalNativeBuild{
cmake{
path 'CMakeLists.txt'
}
}
}
然后在app目錄下創建CMakeLists.txt檔案,名字和大小寫不能寫錯

# CMakeLists.txt
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
#CMakeLists.txt
#指定 cmake 的最小版本這行命令是可選的,我們可以不寫這句話,但在有些情況下,如果 CMakeLists.txt 檔案中使用了一些高版本 cmake
#特有的一些命令的時候,就需要加上這樣一行,提醒用戶升級到該版本之后再執行 cmake,
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
#add_executable(demo demo.cpp) # 生成可執行檔案
#add_library(common STATIC util.cpp) # 生成靜態庫
#add_library(common SHARED util.cpp) # 生成動態庫或共享庫
add_library(
# 設定so檔案名稱.
Hello
# 設定這個so檔案為共享.
SHARED
# Provides a relative path to your source file(s).
src/main/jni/Hello.c)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
# 制定目標庫.
Hello
# Links the target library to the log library
# included in the NDK.
${log-lib} )
4.4 呼叫JNI 方法
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String result = new JNI().sayHello();
Log.d(TAG, "the string from JNI C '"+result + "'");
}
}
運行結果:

記錄一個小問題,正常來講編譯運行后在下面的路徑中我們可以看到指定的幾個架構平臺產出的.so庫檔案,我在學習時直接在模擬器上運行只產生了一個和模擬器架構相同的.so檔案,但是我打包解壓后在lib檔案夾下能看見指定的所有平臺.so檔案,就在我寫博客截圖時,下面的路徑它又都有了,


參考博客 https://blog.csdn.net/sevenjoin/article/details/104531190
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/226900.html
標籤:其他
