android studio + NDK + JNI
来源:互联网 发布:mac解压缩软件自带 编辑:程序博客网 时间:2024/05/24 04:51
推荐:
android studio 中 添加.so 文件
JNI介绍:
Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行交互操作。
JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。
首先看一下Android平台的框架图:
可以看到Android上层的Application和ApplicationFramework都是使用Java编写,
底层包括系统和使用众多的LIiraries都是C/C++编写的。
所以上层Java要调用底层的C/C++函数库必须通过Java的JNI来实现。
android JNI是连接android Java部分和C/C++部分的纽带,完整使用JNI需要Java代码和C/C++代码。其中C/C++代码用于生成库文件,Java代码用于引用C /C++库文件以及调用C/C++方法。
NDK介绍
Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”。
NDK提供了一份稳定、功能有限的API头文件声明
Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。
NDK产生的背景:
Android平台从诞生起,就已经支持C、C++开发。众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言。但这并不等同于“第三方应用只能使用Java”。在Android SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android平台上,“Java+C”的编程方式是一直都可以实现的。
不过,Google也表示,使用原生SDK编程相比Dalvik虚拟机也有一些劣势,Android SDK文档里,找不到任何JNI方面的帮助。即使第三方应用开发者使用JNI完成了自己的C动态链接库(so)开发,但是so如何和应用程序一起打包成apk并发布?这里面也存在技术障碍。比如程序更加复杂,兼容性难以保障,无法访问Framework API,Debug难度更大等。开发者需要自行斟酌使用。
于是NDK就应运而生了。NDK全称是Native Development Kit。
NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式。NDK将是Android平台支持C开发的开端。
概念:
(1).NDK是一系列工具的集合。帮助开发者快速开发C/C++的动态库。
并能自动将so和Java应用一起打包成apk。这些工具对开发者的帮助是巨大的。
(2).NDK将是Android平台开发支持C开发的开端。
作用:
(1).代码的保护。由于Java层代码很容易被反编译,而C/C++库反编译难度很大。
(2).可以方便的使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
(3).提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
(4).便于移植。用C/C++写的库可以方便的在其他的嵌入式平台上再次使用。
一、新建项目,然后新建module并关联module。
二、下载NDK
Android studio此处有NDK的下载路径,直接下载即可。下载后效果如图。我这里下载过,所以直接显示了NDK的路径。
三、配置:
1、gradle.properties中末尾添加:
android.useDeprecatedNdk=true
如图:
2、新建module的build.gradle中的
①、defaultConfig中的末尾添加:
ndk { moduleName "JniTest" ldLibs "log", "z", "m" abiFilters "armeabi", "armeabi-v7a", "x86" }
注意:moduleName用于后面的:
static { System.loadLibrary("JniTest"); //加载实现了native函数的动态库,只需要写动态库的名字 }
②、buildTypes中的末尾添加:
sourceSets { main { jni.srcDir '/src/main/jni' } }
注意:这里jni.srcDir是jni文件夹位置
效果如图:
四、定义native方法并编译
1、在新建的module中新建NdkString类,加载动态库,并定义native方法。
2、build - make module : 编译Java文件成class,找到生成的class文件如图即为成功。
五、生成头文件
打开文件夹看到如图:
然后cmd打开命令行,执行
C:\Users\Administrator>e:E:\>cd E:\android\MyApplication4\mylibrary\src\mainE:\android\MyApplication4\mylibrary\src\main>javah -d jni -classpath ..\..\build\intermediates\classes\debug com.example.mylibrary.NdkStringE:\android\MyApplication4\mylibrary\src\main>
第一、二行,进入module的src/main目录
第三行,javah命令生成头文件,
第四行,表示成功生成,
成功生成后src/main目录下会生成Jni文件夹和头文件。如下图:
六、写c的逻辑
1、新建c文件:hello.c,引入头文件并将头文件的
JNIEXPORT jstring JNICALL Java_com_example_mylibrary_NdkString_getFromC (JNIEnv *, jclass);
复制到hello.c
2、实现自己的一些逻辑,这里直接返回一个字符串
#include "com_example_mylibrary_NdkString.h"JNIEXPORT jstring JNICALL Java_com_example_mylibrary_NdkString_getFromC (JNIEnv * env, jclass jclass){ //return (*env)->NewStringUTF(env,"From C"); return (*env)->NewStringUTF(env,"Hello From JNI!");}
3、jni目录下添加一个空的c文件。
效果如图:
注意:jni文件夹必须新建一个空的c文件,此为windows的bug。
七、生成so文件
rebuild project,然后根据目录找到so,即表示生成生成。
八、调用c文件:
布局:
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.administrator.myapplication.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onclick" android:text="我是原生的Android字符串" /></android.support.constraint.ConstraintLayout>
Java文件:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void onclick(View view) { ((Button) view).setText(NdkString.getFromC()); }}
运行效果如图:
参考:
慕课网
Android开发之Android Studio NDK开发步骤
- android studio + NDK + JNI
- Android Studio NDK jni 开发
- android studio NDK-JNI调用
- Android Studio ndk-Jni开发
- Android Studio NDK/JNI开发
- Android studio jni Ndk 配置
- Android Studio-NDK-JNI调用
- Android Studio ndk-Jni开发
- Android Studio NDK JNI 配置
- android studio初试ndk,jni
- android studio jni ndk 例子
- Android Studio开发NDK JNI
- Android Studio NDK JNI 实践
- Android Studio JNI NDK编程(一)
- Android Studio通过JNI调用NDK程序
- Android Studio下NDK—JNI初涉
- Android studio中如何使用Ndk(Jni)?
- Android studio JNI(NDK) 开发
- 【已解决】Android Studio编译OsmAnd出现警告:GeoPointParserUtil.java使用或覆盖了已过时的 API。有关详细信息请使用-Xlint:deprecation重新编
- oauth协议
- 统计曲线怎么找波峰
- 移动端资源
- 文件字节流与字符流
- android studio + NDK + JNI
- android停止一秒钟
- Md5加密
- 社会实践调研报告-关于大学生网络生活的调研报告
- Spinner三级联动,解析JSON省 市 区,超简单一步搞定
- 三个数比较大小
- 文件上传与下载Demo
- fatal error C1189: #error : missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS
- javaee 是什么,如何获取各种规范jar包,各种规范的实现的jar包