前言

  不废话太多,Java与C之间联系的JNI的概念,这个要了解可以参考下面这个博客:

  https://www.jianshu.com/p/87ce6f565d37

  此博客只说明如何将.C文件通过NDK打包成so库并且使用的一个简单demo.

第一步 创建用于引用本地os库的Java工具类

目录

工具类代码

package zq.ndkdemo;

public class NDKTools {

    static {
System.loadLibrary("ndkdemomk-jni");//这里的"ndkdemomk-jni"是下面.mk文件里局部模块的值,这个到后面我会解释
} public static native String getNDKcontent();//您在Java里调用so库的静态方法
}

第二步 将Java工具类打包成.h文件

打开Android studio的Terminal准备用javah打包.h文件, cd进入到app/src/目录下 然后输入 javah -o ndkdemoHFile.h -jni -classpath ./main/java/  zq.ndkdemo.NDKTools 命令.(下面会解释这条命令)

解释一下这行命令

javah -o ndkdemoHFile.h -jni -classpath ./main/java/  zq.ndkdemo.NDKTools
javah -o 你要打包的.h文件名加后缀 -jni -classpath 中间的路径 app包名+工具类名

输入这条命令后,如果没报错,你就会在src目录下获得您的.h文件,如下图:

打开.h可以看到:

/* 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文件夹并且将.h文件移入

在main目录下创建一个jni文件夹

将我们打包好的.h文件移动到jni文件夹里

第四步 创建c语言函数文件

进入到jni文件夹里,点击创建任意名称加.c后缀的文件

打开写入代码如下:

#include "ndkdemoHFile.h" 

JNIEXPORT jstring JNICALL Java_zq_ndkdemo_NDKTools_getNDKcontent
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"Hellow World,这是NDK的第一行代码");
}

注意!代码里最好别写注释特别是中文注释.

#include "ndkdemoHFile.h"

这行代码引用的就是.h文件名称

JNIEXPORT jstring JNICALL Java_zq_ndkdemo_NDKTools_getNDKcontent

这行代码中 jstring 为返回值

Java_zq_ndkdemo_NDKTools_getNDKcontent  为 Java + 路径 + 类名 + 方法名称

第五步 创建.mk文件

在jni目录下创建一个叫Android.mk的文件

内容如下:

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

LOCAL_MODULE模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。Build System 会自动添加适当的前缀和后缀。例如,demo,要生成动态库,则生成libdemo.so。但请注意:如果模块名字被定义为libabd,则生成libabc.so。不再添加前缀。另外我们一开始写的Java工具类里的System.loadLibrary("ndkdemomk-jni"); 就是这个值

OCAL_SRC_FILES := ndkdemCFile.c

这行代码表示将要打包的C/C++源码。不必列出头文件,build System 会自动帮我们找出依赖文件。缺省的C++ 源码的扩展名为.cpp。

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:该模块已经预先编译

第六步 在build.gradle文件里添加部分代码

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 = []
}
} }

第七步  检查Android studio是否已经下载配置过ndk

点击local.properties打开

 
查看是否有ndk
ndk.dir=/media/E/tools/SDK/androidsdklinux/ndk-bundle
sdk.dir=/media/E/tools/SDK/androidsdklinux

如果没有就需要进入到File >> Settings  里下载ndk

 

第八步 编译SO文件

在Android studio的工具栏里,点击Build >> clean Project  先清理一下之前的编译

在点击Build >> Rebuild Project  重新创建编译文件

然后可以打开下图所示路径,就可以看到我们的so文件了

第九步 调用工具类方法,run APP

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 即可.

Android 开发 DNK开发将.c文件打包成os的更多相关文章

  1. windows下如何将Python文件打包成.exe可执行文件

    在使用Python做开发的时候,时不时会给自己编写了一些小工具辅助自己的工作,但是由于开发依赖环境问题,多数只能在自己电脑上运行,拿到其它电脑后就没法运行了.这显得很不方便,不符合我们的初衷,那么有没 ...

  2. PyQt(Python+Qt)学习随笔:windows下使用pyinstaller将PyQt文件打包成exe可执行文件

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 在<windows下使用pyinstaller将多个目录的Pyt ...

  3. windows下使用pyinstaller将多个目录的Python文件打包成exe可执行文件

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 需要将一个工程涉及两个目录的模块文件打包成exe,打包环境如 ...

  4. 把java文件打包成.jar (jar命令详解)

    把java文件打包成.jar (jar命令详解) 先打开命令提示符(win2000或在运行框里执行cmd命令,win98为DOS提示符),输入jar Chelp,然后回车(如果你盘上已经有了jdk1. ...

  5. 如何将class文件打包成jar 这里提供两种方式!

    原地址:http://blog.163.com/09zzy@126/blog/static/711976652011101001530/ 如何将class文件打包成jar文件,这是一个很严肃的问题,当 ...

  6. 使用Eclipse把java文件打包成jar 含有第三方jar库的jar包

    使用Eclipse把java文件打包成jar 含有第三方jar库的jar包   网上打包说用eclipse安装fat jar插件,但是貌似现在都不能用了,所以我只能按照eclipse自带的方法打包了. ...

  7. python的py文件打包成exe

    一.首先需要安装Pyinstaller-- 使用pip来安装模块 (我电脑上装的是python的一个编译环境Anaconda,如果电脑上装的是python自带的IDE的话,就直接进入python的安装 ...

  8. Ubuntu下将现有的文件打包成deb包

    转自:http://www.linuxidc.com/Linux/2008-04/12297.htm deb是Debian Linux的软件包格式.一般来说是需要通过编译源码然后制作deb包,今天由于 ...

  9. 如何把py文件打包成exe可执行文件

    如何把py文件打包成exe可执行文件 1.安装 pip install pyinstaller 或者 pip install -i https://pypi.douban.com/simple pyi ...

随机推荐

  1. COGS2353 【HZOI2015】有标号的DAG计数 I

    题面 题目描述 给定一正整数n,对n个点有标号的有向无环图(可以不连通)进行计数,输出答案mod 10007的结果 输入格式 一个正整数n 输出格式 一个数,表示答案 样例输入 3 样例输出 25 提 ...

  2. mkdir: Cannot create directory /file. Name node is in safe mode.

    刚刚在hadoop想创建一个目录的时候,发现报错了 具体信息如下: [hadoop@mini1 hadoop-2.6.4]$ hadoop fs -mkdir /file mkdir: Cannot ...

  3. excel破解工作簿与工作表保护

    1.工作簿保护 1.1.使用压缩文件打开文件

  4. thinkphp 模型定义

    模型定义 模型类并非必须定义,只有当存在独立的业务逻辑或者属性的时候才需要定义. 模型类通常需要继承系统的\Think\Model类或其子类,下面是一个Home\Model\UserModel类的定义 ...

  5. gitbook新版本"gitbook build"命令导出的html不能跳转的解决办法

    使用的是win7系统,gitbook新版本不支持html跳转功能,所以要降版本至2.6.7 解决办法如下: 第一步: 生成时指定gitbook的版本, 本地没有会先下载 gitbook build - ...

  6. day4:Python列表(list)元组( tuple)字典(dict)

    列表----list 列表:中括号,每个元素用‘,’分割,列表里面也可以嵌套列表,列表里面可以包含数字,字符串,布尔值等,也就是元素的集合 例:test = [2,4,'sun','yao'] #索引 ...

  7. 第二篇:怕碰到是因为没掌握,来吧,zTree!

    一直以来看见web项目中的树就头疼.这次又给碰上了,什么也别说,这次自己整理一个版本出来实践一下.zTree v3.2的API界面非常清爽,但是在查看API之前,你需要自己先实践一下,知道基本的概念和 ...

  8. 第五周课堂笔记1th

    可迭代对象   Isinstance  判断一个对象是否属于某种类型 接受两个参数 迭代器 以下数据类型都没迭代器: 把没有迭代器的类型更改为有迭代器类型 用迭代器进行取值: 判断迭代器的方法: 3. ...

  9. 2019 Multi-University Training Contest 6 Snowy Smile (最大字段和变形)

    题意: 求一个子矩阵要求其矩阵内的合最大. 题解: 正常的求最大子矩阵的复杂度是O(n^3) 对于这一题说复杂度过不去,注意到这个题总共只有2000个点关键点在与这里优化 最大子矩阵可以压缩矩阵变成最 ...

  10. CSS清除默认边距

    body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquo ...