JNI初探

来源:互联网 发布:程序员的数学3 编辑:程序博客网 时间:2024/06/18 15:26
声明:转自文章:http://www.itnose.net/detail/6303169.html
每次修改c文件后记得编译!

Native Development Kit

下载NDK开发包

传送门在这:http://download.csdn.net/detail/qq_27258799/9237447

选择NDK r10e 
android-ndk-r10e-windows-x86_64.exe 
自解压文件大小400M,解压后3G+。

配置NDK环境变量

这里写图片描述 
将ndk目录添加到系统环境变量path,然后在新打开的cmd输入ndk-build验证: 
这里写图片描述

HelloJni

Eclipse安装ADT的时候,安装的有Android Native Development Tools, 
导入位于android-ndk-r10e\samples\hello-jni的例子到Eclipse: 
这里写图片描述

初始的目录结构: 
这里写图片描述

然后打开cmd,切换到HelloJni项目目录: 
执行ndk-build进行编译: 
这里写图片描述

完成后回到Eclipse刷新HelloJni目录,发现增加了obj文件夹,里面有各个架构对应的.so库文件,如下图: 
这里写图片描述

然后运行工程: 
这里写图片描述

注意到上面执行ndk-build时,编译了很多架构,时间会长一些,如果只想编译我们需要的arm,可以将项目jni目录下的Application.mk文件的以下内容进行注释:

#APP_ABI := all

清除上次的编译:

ndk-build clean

这里写图片描述

再次ndk-build,很快完成: 
这里写图片描述

第一个NDK项目

1.新建Android项目 
在MainActivity里创建一个native方法:

    public static native String getStringFromC();

2.创建jni目录 
3.编写java层native方法 
4.生成JNI头文件

  • javah

这里写图片描述 
cmd切换到项目目录,然后执行: 
javah -classpath bin/classes -d jni com.zms.hellondk.MainActivity

这里写图片描述 
javah -classpath bin/classes;D:\Android\sdk\platforms\android-22\android.jar -d jni com.zms.hellondk.MainActivity
这样比较麻烦,也可以: 添加android.jar到环境变量:D:\Android\sdk\platforms\android-22\android.jar 
这里写图片描述

可以看到jni目录下生成了.h头文件: 
这里写图片描述

格式如下: 
这里写图片描述

然后在jni目录下创建我们自己的c文件: 
hello.c

#include<stdio.h>#include<stdlib.h>#include"com_zms_hellondk_MainActivity.h"JNIEXPORT jstring JNICALL Java_com_zms_hellondk_MainActivity_getStringFromC(        JNIEnv env, jclass jclass) {    return (*env)->NewStringUTF(env, "Hello from JNI !");}

然后在jni目录下创建Android.mk文件: 
Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := HelloNdkLOCAL_SRC_FILES := hello.c #对哪个c文件进行编译include $(BUILD_SHARED_LIBRARY)

然后进入cmd切换到工程目录进行编译: 
这里写图片描述

注意,MainActivity里要写加上loadLibrary,引号里是Module名,static区声明的代码会先于onCreate方法执行:

package com.zms.hellondk;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.TextView;public class MainActivity extends Activity {    public static native String getStringFromC();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        TextView textFromJni = (TextView) findViewById(R.id.textFromJni);        textFromJni.setText(getStringFromC());    }    static {        System.loadLibrary("HelloNdk");    }}

否则会出现以下错误: 
这里写图片描述

(- -,不要问我是怎么知道的)

NDK相关概念

  • NDK的应用场景 
  • 代码的保护(Java代码容易被反编译,C/C++库)
  • 代码复用性:多数开源库用C/C++编写(如OpenCV,FFmpeg等)
  • 便于移植(在其他嵌入式平台上再次使用,如iOS)
  • 交叉编译

    使用工具在一个平台编译生成另一个平台可执行的代码。

  • JNI(Java Native Interface)

    是Java平台标准的一部分,允许Java代码和其他语言代码进行交互 
    这里写图片描述

  • 链接库(静态,动态)

  • 静态链接库
  • 动态链接库
  • mk配置文件(make)参数
  • ndk开发包目录

1 0
原创粉丝点击