不廢話太多,Java與C之間聯繫的JNI的概念,這個要了解能夠參考下面這個博客:java
https://www.jianshu.com/p/87ce6f565d37linux
此博客只說明如何將.C文件經過NDK打包成so庫而且使用的一個簡單demo.android
package zq.ndkdemo; public class NDKTools { static { System.loadLibrary("ndkdemomk-jni");//這裏的"ndkdemomk-jni"是下面.mk文件裏局部模塊的值,這個到後面我會解釋 } public static native String getNDKcontent();//您在Java裏調用so庫的靜態方法 }
javah -o ndkdemoHFile.h -jni -classpath ./main/java/ zq.ndkdemo.NDKTools
javah -o 你要打包的.h文件名加後綴 -jni -classpath 中間的路徑 app包名+工具類名
打開.h能夠看到:app
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class zq_ndkdemo_NDKTools */ #ifndef _Included_zq_ndkdemo_NDKTools #define _Included_zq_ndkdemo_NDKTools #ifdef __cplusplus extern "C" { #endif /* * Class: zq_ndkdemo_NDKTools * Method: getNDKcontent * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_zq_ndkdemo_NDKTools_getNDKcontent (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
進入到jni文件夾裏,點擊建立任意名稱加.c後綴的文件ide
打開寫入代碼以下:函數
#include "ndkdemoHFile.h" JNIEXPORT jstring JNICALL Java_zq_ndkdemo_NDKTools_getNDKcontent (JNIEnv *env, jobject obj){ return (*env)->NewStringUTF(env,"Hellow World,這是NDK的第一行代碼"); }
注意!代碼裏最好別寫註釋特別是中文註釋.工具
這行代碼引用的就是.h文件名稱gradle
這行代碼中 jstring 爲返回值ui
Java_zq_ndkdemo_NDKTools_getNDKcontent 爲 Java + 路徑 + 類名 + 方法名稱
spa
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := ndkdemomk-jni LOCAL_SRC_FILES := ndkdemoCFile.c include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
:每一個Android.mk文件必須以定義開始。它用於在開發tree中查找源文件。宏my-dir
則由Build System 提供。返回包含Android.mk目錄路徑。
include $(CLEAR_VARS)
:CLEAR_VARS
變量由Build System提供。並指向一個指定的GNU Makefile,由它負責清理不少LOCAL_xxx。例如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_STATIC_LIBRARIES等等。但不是清理LOCAL_PATH。這個清理是必須的,由於全部的編譯控制文件由同一個GNU Make解析和執行,其變量是全局的。因此清理後才能便面相互影響。
LOCAL_MODULE := ndkdemomk-jni
:OCAL_SRC_FILES := ndkdemCFile.c
:include $(BUILD_SHARED_LIBRARY)
:BUILD_SHARED_LIBRARY
是Build System提供的一個變量,指向一個GUN Makefile Script。它負責收集自從上次調用
include $(CLEAR_VARS)
後的全部LOCAL_xxxxinx。並決定編譯什麼類型
BUILD_STATIC_LIBRARY
:編譯爲靜態庫BUILD_SHARED_LIBRARY
:編譯爲動態庫BUILD_EXECUTABLE
:編譯爲Native C 可執行程序BUILD_PREBUILT
:該模塊已經預先編譯android { compileSdkVersion 28 defaultConfig { applicationId "zq.ndkdemo" minSdkVersion 27 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" //須要添加的部分 ndk{ moduleName "ndkdemo-jni" abiFilters "armeabi-v7a", "x86" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } //須要添加的部分 externalNativeBuild { ndkBuild { path 'src/main/jni/Android.mk' } } //須要添加的部分 sourceSets.main { jni.srcDirs = [] jniLibs.srcDirs = ['src/main/jniLibs'] } } //須要添加的部分 sourceSets{ main { jni.srcDirs = [] } } }
點擊local.properties打開
ndk.dir=/media/E/tools/SDK/androidsdklinux/ndk-bundle
sdk.dir=/media/E/tools/SDK/androidsdklinux
若是沒有就須要進入到File >> Settings 裏下載ndk
在Android studio的工具欄裏,點擊Build >> clean Project 先清理一下以前的編譯
在點擊Build >> Rebuild Project 從新建立編譯文件
而後能夠打開下圖所示路徑,就能夠看到咱們的so文件了
public class MainActivity extends AppCompatActivity { private TextView mDemoText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDemoText = findViewById(R.id.demo_text); String content = NDKTools.getNDKcontent(); mDemoText.setText(content); } }
運行APP 便可.