Android平台上的JNI开发之Hello JNI

先有个概念

JNI,洋名全称是Java Native
Interface,翻译过来就是Java本地接口。我们都知道所谓接口就是一套规范,可以用来定义接入方式。那么JNI定义了何等衔接形式呢?答案是:它定义了一套Java接入C/C++的不二法门。

咱俩领悟C/C++语言编译后的文件是可以直接在该地系统中运作的,而Java文件编译后生成的是字节码文件,必要倚重Java虚拟机(JVM)来运作,鲜明在功效上C/C++更高效;另一方面,大家驾驭字节码文件是足以很简单反编译的,存在不安全性;再者,硬件相关的驱动、许多远近闻名的音视频解码库也是C/C++编写的。Java程序想要执行高品质的代码、想要高安全性要么必要调用系统驱动和重用已有个别音录制解码库,那么就只可以接纳JNI了。

看下小编那会儿简陋的笔记:

JNI笔记-概念

原理

大约的进程是那样的:

  1. 咱俩把C/C++源程序编译打包成动态库(dll或so,具体看运维的环境),存放在大家先后的lib目录下;
  2. 在java程序中我们调用带native修饰的代理方法,它的贯彻在C/C++程序中,系统会调用动态库中相应的落实方式,即使要求的话,还会重回处理结果。

JNI笔记-原理

JNI开发环境搭建

听你那样一说,原理似乎懂了些了,那将来是或不是该开工了??别急,“工欲善其事,必先利其器”,让大家先搭建起开发条件。

1. 下载NDK

What ? NDK是怎样鬼?别急嘛,那就说。NDK洋名全称是Native Development
Kit,就是谷歌给我们开发者提供的一套有利于地拓展JNI开发的工具集,可以到官网下载,也足以用自个儿准备好的财富(里面还蕴藏了适用于eclipse开发环境的NDK插件,那一个在ADT-Bundle中是融为一体的)。

2. 解压NDK并查阅参考文档

将下载后的缩减包解压到任意分区,注意文件路径不能包涵普通话和空白字符(比如空格、tab),否则会促成NDK不可用。注:可以透过翻看参考文档和导入示例代码到工程学习。

NDK目录

3. 设置NDK插件和绑定NDK路径

对Eclipse
IDE:放到eclipse安装目录下的plugins目录就对了,然后依次点击Window–>Preference–>Android–>NDK
实行NDK路径的绑定

绑定步骤1

绑定步骤2

JNI笔记-搭建开发条件

Hello JNI

如果地点的手续顺利,上面大家就要正式跟JNI打个招呼了。Hello
JNI项目源码:下载

1. 新建二个平凡的Android项目

简单,略。

2. 添加本地动态库帮助

右击Android项目–>Android Tools–>Add Native
Support…,然后输入动态库的名目(系统会活动抬高前缀”lib”和后缀”.so”,以jni为例)

充裕本地动态库协助1

累加本地动态库匡助2

做到后会发现,工程会转到C/C++视图,并且项目中多了有个别文件/文件夹

多了的公文

3. 创立七个照应的文书

3个是Java源文件,代理动态库中方法;另2个是C/C++源文件,是对代理方法的兑现。
一级实践是:先创制Java代理文件,静态导入动态库并编写好代理方法,然后采取javah命令生成C语言的法门签名;复制方法签名到C/C++源文件中,补充参数名和方法体就OK了。

3.1 创建Java源文件–Jni.java
package com.example.hello_jni;
public class Jni {
    //静态加载我们即将生成的so库
    static{
        System.loadLibrary("jni");
    }
    //代理函数,具体实现在C
    public native String getMsgFromC();
}
3.2 生成Jni.java的标头文件

复制工程的src目录的地方,当前为:D:\Android\jni\Hello-JNI\src
CMD进入

C:\Users\Lshare>cd /d D:\Android\jni\Hello-JNI\src
D:\Android\jni\Hello-JNI\src>

复制Jni.java的所有径名,当前为:com.example.hello_jni.Jni
javah生成标头文件

D:\Android\jni\Hello-JNI\src>javah com.example.hello_jni.Jni

刷一下工程,可以看看

标头文件

3.3 复制标头文件内容到jni.cpp,并剔除标头文件(com_example_hello_jni_Jni.h)

jni-未绑定.png

3.4 绑定头文件路径

绑定头文件1

绑定头文件2

绑定头文件3

绑定头文件4

绑定头文件5

4.成功函数体

#include <jni.h>
/**
 * env:包含了jni.h提供了许多便捷的函数,查看头文件源码发现
 * #if defined(__cplusplus)
 * typedef _JNIEnv JNIEnv;
 * typedef _JavaVM JavaVM;
 * #else
 * typedef const struct JNINativeInterface* JNIEnv;
 * typedef const struct JNIInvokeInterface* JavaVM;
 * thiz:包含对应的代理函数的java类的对象
 */
#ifndef _Included_com_example_hello_jni_Jni
#define _Included_com_example_hello_jni_Jni
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL Java_com_example_hello_1jni_Jni_getMsgFromC
  (JNIEnv * env, jobject thiz){
    //当为cpp文件时用“env->”,为c文件时用“(*env)->”
    // 该函数用于将“C-String”转换为jstring
    return env->NewStringUTF("Hello JNI!");
}
#ifdef __cplusplus
}
#endif
#endif

5. 完美逻辑已毕

//activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:onClick="sayHello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="C快快请安" />
</RelativeLayout>

//MainActivity.java
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void sayHello(View view){
        String msg = new Jni().getMsgFromC();
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }
}

6. 修改Android.mk和Application.mk适应要求

Android.mk的天职:描述源文件该怎样编译

#包含Android.mk自身的路径
LOCAL_PATH := $(call my-dir)
#清除LOCAL_XXX变量,除了LOCAL_PATH
include $(CLEAR_VARS)
#要生成的动态库名称,系统会自动加上“lib”前缀和“.so”后缀
LOCAL_MODULE    := jni
#要编译的C/C++文件
LOCAL_SRC_FILES := jni.cpp
#指向构建脚本,搜集定义的LOCAL_XXX变量信息,生成lib$(LOCAL_MODULE).so
include $(BUILD_SHARED_LIBRARY)

Application.mk的任务:描述哪三个动态库是连串需求的
暗许不生成那一个文件,大家须要本身在/jni目录下新建多个。一般景观下,大家采取七个变量就够了

#定义要生成的CPU架构的so文件,all代表所有
APP_ABI := all
#目标安卓版本,18表示api level,即Android 4.3
APP_PLATFORM := android-8

7. run转眼探视

运转结果

Java果真通过JNI技术调用了C代码,而C真的归来问候给Java了,nice!!!


末段不妨看看本人那时的笔记(仅供参考,估计唯有本身要美观得懂,捂脸走。。。)

JNI笔记- Hello JNI