前言

  不废话太多,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. 实现虚拟机VMware上Linux与本机windows互相复制与粘贴的问题

    解决方法:只需要在Linux系统中安装一个vmware-tools的工具 1.选择虚拟机菜单,有安装vmware tools 工具的选项 点击之后,在Linux的桌面下会出现 VMwareTools. ...

  2. datetime模块练习

    #_author:来童星#date:2019/12/6#1.获取当前日期import datetimeprint(datetime.date.today())# 2019-12-06#2.使用toda ...

  3. 基于Element-UI的el-table,input框输入实现排序功能

    最终效果如下 实现要求: 如果输入的内容不是非负整数,那么提示报错,并且将值变为输入前的内容: 如果输入正确,则当输入的内容发生改变并且失去焦点以后,触发事件,重新获取列表: 实现思路 使用原生的in ...

  4. 「题解」:$Simple$

    问题 A: $Simple$ 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 不算数学的数学题?? 直接枚举会重.$60%$两种算法:1.无脑$vis$数组记录.2.$ ...

  5. C++仿函数和回调函数的异同

    C++回调函数(callback)与仿函数(functor)的异同 c++仿函数 functor C++仿函数和回调函数的异同

  6. 进程通信类型 管道是Linux支持的最初Unix IPC形式之一

    管道 Linux环境进程间通信(一) https://www.ibm.com/developerworks/cn/linux/l-ipc/part1/index.html 管道及有名管道 郑彦兴200 ...

  7. Activity详解一 配置、启动和关闭activity转载 https://www.cnblogs.com/androidWuYou/p/5887726.html

    先看效果图: Android为我们提供了四种应组件,分别为Activity.Service.Broadcast receivers和Content providers,这些组建也就是我们开发一个And ...

  8. ICPC 2018 徐州赛区网络赛

    ACM-ICPC 2018 徐州赛区网络赛  去年博客记录过这场比赛经历:该死的水题  一年过去了,不被水题卡了,但难题也没多做几道.水平微微有点长进.     D. Easy Math 题意:   ...

  9. 第四周课堂笔记2th

    2. 在函数中*对于形参的作用是聚合,对于实参的作用是打散 3. 加载顺序:内置——全局——局部空间 取值顺序:局部——全局——内置空间 左上角的答案: 123 666 888 777 右边的答案:7 ...

  10. 使用CEfSharp之旅(1) 加载网络页面

    原文:使用CEfSharp之旅(1) 加载网络页面 版权声明:本文为博主原创文章,未经博主允许不得转载.可点击关注博主 ,不明白的进群191065815 我的群里问 https://blog.csdn ...