From:Android Studio 3.0 JNI 的實現:https://blog.csdn.net/ziyoutiankoong/article/details/79696279
Android Studio 3.0 SO文件的引用:https://blog.csdn.net/ziyoutiankoong/article/details/79700879
android studio 3.0 JNI 使用:https://www.jianshu.com/p/190a242fd7ab
Android Studio jni開發入門——看我就夠了!:https://www.jianshu.com/p/28d541d658db
Android Studio開發之 JNI 篇:https://www.jianshu.com/p/c993928e8081
android studio 3.4 配置 Android -jni 開發基礎的教程詳解:https://www.jb51.net/article/169438.htm
基於Android studio3.6 的JNI教程之helloworld思路詳解:https://www.jb51.net/article/182804.htm
Android Studio 開發 JNI 示例:https://blog.csdn.net/wzhseu/article/details/79683045
JNI 技術的整體步驟和原理:
1、新建一個Android studio工程(注意 把這個勾選上,不然後面還需要配置,勾選上就無須自己配置Cmake,Gradle啦)
2、Android 指定位置新建一個類,如JavaJNI.java類(一般位置爲、src/main/java/"你的包名"/),在該類裏面聲明一個方法,該方法有本地端實現,即如 public native void open();
3、寫好之後本地native方法之後,配置Javah, 操作步驟:File-Tools-External Tools-"點擊加號" name隨便起一個,方便統一叫javah, 下面的Description可以和上面一致;
Program: $JDKPath$\bin\javah.exe
Auguments: -classpath . -jni -o $ModuleFileDir$/src/main/jni/$Prompt$ $FileClass$
Working directory: $ModuleFileDir$\src\main\java
以上爲配置Javah過程,到這就配置好了,注意上面幾個配置你可以理解爲固定配置,其實是一些路徑定義,可以不用管的,
4、鼠標選中剛剛新建的含有本地實現方法的類,右擊選擇External Tools的Javah, 隨機在彈出的窗口輸入名字(這個名字就是馬上生成的C或C++頭文件的名字,文件會保存在/src/main/jni/下面),這樣我們的C或C++頭文件就生成好了,在JNI文件下,
5、將生成的.h頭文件 放到、src/main/cpp文件中
6、在cpp文件下在新建一個對應的.cpp文件,開始編寫需要調用的本地函數方法(具體做法把剛生成.h文件中的方法名複製過來,“;”改爲方法體“{}”,然後在方法體中用C++實現你需要的功能)
7、在MainActivity.java測試類中調用JavaJNI.java類中本地聲明的方法
8、編譯即可成功調用實現你寫的C++方法
1. NDK 安裝配置
在 File - Settings ...,下查看 NDK 安裝配置情況,如果沒有下載配置 NDK ,以及相關的包,對應下載相關的安裝包。
具體如下圖
打開 sdkManager下載 CMake 和 LLDB
配置 ndk
下載安裝好後,可以在 File - Project Structure 的 SDK Location 下查看對應的安裝配置路徑情況,
2. 打開 Android Studio,新建一個 Native C++工程。
具體如下圖
輸入工程名:JNINDK
然後,點擊 完成:
成功創建 Android 項目 (JNIDemo)
如圖:
創建 jni 文件夾:src 右鍵 ---> New ---> Folder ---> JNI Folder 如圖:
選擇 JNI Folder :
結果如圖:
3. 創建 JNI 類
示例代碼:
public class JNITest {
static {
System.loadLibrary("JniLib");
}
public native String getString();
}
如圖:
3.1 生成 .h 文件
方法 1:
配置 Anroid Studio 外部工具,一勞永逸,往後無需命令行,File ---> Setting ---> Tools ---> External Tools ---> “+” 進入頁面
添加外部命令:
配置命令:
Program:$JDKPath$\bin\javah.exe
Parameters:-classpath . -jni -d $ModuleFileDir$\src\main\jni $FileClass$
Working directory:$ModuleFileDir$\src\main\Java
註釋:
-classpath classes 指明類所在的位置
-jni com.jni.jnitest.JNITest 類的絕對路徑
-d 產生的.h文件放到指定目錄下;
配置成功如圖:
開始生成 .h文件,選中 JNI類 右鍵 ---> New ---> External Tools ---> javah,如圖:
成功後如圖:
方法 二
右鍵拖動JNI類所在的包的路徑到Terminal,自動切換到該目錄下
javac 編譯生成 class 文件( 生成class文件的方法有很多,這裏提供一種)
右鍵拖動 java 文件夾到 Terminal,自動切換到該目錄下
必須在包名外使用 javah 命令,編譯生成.h文件,把.h文件移動到jni文件夾(生成.h文件後可以刪除class文件)如圖:
示例命令:javah -d jni -classpath ./java com.example.myapplication.hello
3.2 創建文件 JniLib.cpp 、Android.mk、Application.mk
在 jni 目錄下分別創建並編寫 JniLib.cpp、Android.mk、Application.mk 這三個文件
複製.h文件內容到 JniLib.cpp 並修改,如下(此文件爲JNI內容文件):
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <com_jni_jnitest_JNITest.h>
/* Header for class com_jni_jnitest_JNITest */
/*
* Class: com_jni_jnitest_JNITest
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jni_jnitest_JNITest_getString
(JNIEnv * env, jobject jobject){
return (*env).NewStringUTF("成功調用JNI內容");
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JniLib
LOCAL_SRC_FILES =: JniLib.cpp
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_MODULES := JniLib
APP_ABI := all
4. 其它相關配置
4.1 修改 app下的 build.gradle 文件, 如下圖
示例代碼:
ndk{
moduleName "JniLib"
// abiFilters "armeabi", "armeabi-v7a", "x86" //輸出指定的三種abi體系下的so庫
}
sourceSets.main{
jni.srcDirs = []
jniLibs.srcDir "src/main/libs"
}
4.2 項目下的gradle.properties文件(如果沒有此文件,自己新建一個)添加代碼:
android.useDeprecatedNdk=true
5. 執行 ndk-build
此處我用的是配置好的工具來執行,和 javah 外部工具 一樣的步驟
選中JNI類右鍵->New->External Tools->ndk-build,結果如圖:
6. 調用 so
示例代碼:
package com.jni.jnitest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Button button;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
tv = findViewById(R.id.tv);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
tv.setText("結果:"+ new JNITest().getString());
}
});
}
}
結果
demo 下載:https://download.csdn.net/download/u013015029/10309365