C语言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,就是Google给我们开发者提供的相同仿有利于地开展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. 创两独照应之公文

一个凡是Java源文件,代理动态库中法;另一个是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