不废话太多,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 便可.