Android studio編寫第一個NDK工程的過程詳解,以及Demo下載地址
首先附上我的幾篇其它文章鏈接感興趣的可以看看,如果文章有異議的地方歡迎指出,共同進步,順便點贊謝謝!!!
Android framework 源碼分析之Activity啓動流程(android 8.0)
面試必備1:HashMap(JDK1.8)原理以及源碼分析
面試必備2:JDK1.8LinkedHashMap實現原理及源碼分析
Android事件分發機制原理及源碼分析
View事件的滑動衝突以及解決方案
Handler機制一篇文章深入分析Handler、Message、MessageQueue、Looper流程和源碼
Android三級緩存原理及用LruCache、DiskLruCache實現一個三級緩存的ImageLoader
1:創建工程和配置NDK
1:如果之前沒有下載配置ndk則下載
2:給工程配置ndk路徑
方法一:在工程的local.properties
文件中添加ndk.dir=D\:\\SoftPath\\Android\\Sdk\\ndk-bundle
如下圖
方法二:在studio的Project Structure中選擇SDK路徑
2:編寫JNI程序
第二部分主要是JNI相關操作,因爲ndk是基於JNI的
1:創建HelloWord.java類在此類中定義native方法,注意該文件中最好不要有中文字符,我這裏加了一些批註方便理解
public class HelloWord {
public static native String getString();//從native方法獲取一個字符串
public static native int add(int a,int b);//從native方法做兩個數字相加並返回結果
}
2:在Terminal窗口編譯HelloWord獲取字節碼文件javac HelloWord.java
注意切換到此文件目錄下或者用絕對路徑,(你也可以用cmd,這兩種方式你都得配置了JDK、NDK的環境變量)
切換目錄執行javac HelloWord.java
執行完javac HelloWord.java
則在當前目錄下生成字節碼文件
3:切換目錄到 \app\src\main文件目錄下執行 javah
生成頭文件
javah -d jni -classpath D:\WorkSpace\JNIDemo\app\src\main\java myh.com.jnimodel.HelloWord
分析命令:
-d jni:當前目錄下創建一個 jni 文件夾
-classpath D:\WorkSpace\JNIDemo\app\src\main\java myh.com.jnimodel.HelloWord 指向字節碼文件的路徑
javah指令的詳細解釋如圖
執行完後會在 main文件夾下創建jni文件夾並生成.h的頭文件 ,給文件中聲明瞭HelloWorld中的native方法
強調一點:生成的myh_com_jnimodel_HelloWord.h文件是爲了不懂c或者c++的碼農方便編寫c或c++的代碼,可以沒有.h文件
4:在jni目錄下新建.c或.cpp文件實現.h文件中定義的接口方法
1:選中jni目錄右鍵–》new—》c/c++ Source File, 名字隨意我這叫hello.c
我用的c語言實現的
2:實現.h中的就扣方法
在這裏解釋一下方法中的兩個重要參數
- JNIEnv *env表示指向JNI環境的指針,通過它來訪問JNI提供的接口方法
- **jclass **作用相當於Java中的this
hello.c文件的代碼
//
// Created by geo on 2019/4/29.
//
#include<jni.h>
#include<stdio.h>
//導入我們創建的頭文件
#include "myh_com_jnimodel_HelloWord.h"
JNIEXPORT jstring JNICALL Java_myh_com_jnimodel_HelloWord_getString
(JNIEnv *env, jclass jclass){
//返回一個字符串
return (*env)->NewStringUTF(env,"This is my first NDK Application");
}
JNIEXPORT jint JNICALL Java_myh_com_jnimodel_HelloWord_add
(JNIEnv *env,jclass jclass, jint a, jint b){
return a+b;
}
3:ndk編譯生成so文件
1:在jni文件下新建 Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello// 生成的so文件名稱
LOCAL_SRC_FILES := hello.c//編譯的c或c++文件
include $(BUILD_SHARED_LIBRARY)
2:在jni文件下新建 Application.mk 指定CPU架構 all代表所有
APP_ABI := all
最後jni目錄有一下四個文件
3:切換目錄到jni目錄下執行ndk-build生成對應的so文件
執行完ndk-build會在與jni同級目錄下生成libs文件夾,該文件夾存放了對應cpu的so文件如下圖
4:調用生成的so文件
1:準備工作:配置Studio加載so文件的路徑
第一種方法: 因爲Android studio默認加載so的路徑是在src\main\jniLibs
,在main下新建jniLibs
文件夾,將libs裏的所有內容都複製到jniLibs下(包括so文件的目錄結構)
第二種方法:就是修改Android studio 加載so文件的路徑,在model的build.gradle
文件中,添加如下代碼sourceSets { main { jni.srcDirs = ['libs'] } }
,注意是android{}標籤中添加
2:加載so庫
System.loadLibrary("hello")
注意hello是上在android.mk中指定的so文件名(即LOCAL_MODULE := hello// 生成的so文件名稱
),實際上我們生成的so文件前默認會加上lib即libhello.so
運行點擊按鈕出現如下結果:返回hello.c文件中方法的數據
到此完畢,最後附上我在編譯時遇到的兩個問題的解決方案和demo的下載地址
Android NDK 運行錯誤:java.lang.UnsatisfiedLinkError: Couldn’t load XXX indLibrary returned null
Android studio3.2出現Your project contains C++ files but it is not using a supported native build