Android之JNI初级篇

JNI – Java Native Interface: Java平台中一个用于和本地C代码进行互操作的API,称为Java本地接口。也就是用来实java程序中调用C函数。实质是将本地C代码编译到一个动态装载库中(libHello.so/Hello.dll)

Android JNI: Android工程中调用C的过程,称为Native Development

本文档通过在Android APP中调用C函数执行Liniux Shell命令来简单介绍一下Native Development

一、 准备

1OSWindows

2Eclipse略。

3NDK(Native Development Kit):用来将C/C++生成的原生代码库嵌入到.apk文件中。下载地址:android-ndk-1.6_r1 ,解压即可。此外,NDK中还包含了从C / C++生成原生代码库所需要的工具和build files。要执行这些build,需要借助下面的Cygwin工具。

4 Cygwin是一个在windows平台上运行的unix模拟环境,使用gnu工具集在windows上进行嵌入式系统开发的优秀工具。下面着重介绍其安装方法:

首先下载安装工具:http://www.cygwin.com/setup.exe

点击执行它,下面是几个关键步骤的截图:

点击下一步 –> 选择Install from Internet –> 下一步 –>选择安装目录 –> 下一步 –> 选择下载文件存放的目录 –> 下一步 –> 选择上网代理:Use Internet Explorer Proxy Settings –> 下一步出现下图:

选择一个下载网站,通过测试,从http://mirrors.163.com下载速度较快,如果列表中没有,可以Add进去。

然后点击下一步,就进入了一个漫长的阶段Downloading,完成后会出现下图:

将箭头指向的Devel@Default点成install然后下一步, 又进入一个漫长的阶段,包括解包,CheckingRunning…

好几个小时后,该阶段结束,直接下一步点击完成安装。桌面出现图标:

点击测试,如果出现下图,则表示安装成功:

接下来用Cygwin执行NDK/build下的host-setup.sh完成NDK的安装。方法:在窗口中通过cd命令进入NDK目录,然后执行build/host-setup.sh.

user@lizq /cygdrive/e/eclipse/android-ndk-1.6_r1

$build/host-setup.sh

出现以上信息表示 Host setup complete。可以先编译一下NDK/apps文件夹中的工程实例,检查NDK是否正常工作.

选择apps/hello-jni做实验, NDK根目录下执行:make APP=hello-jni -B,其中-B参数是始终执行build, 不管C/C++代码是否有修改。如下图:

从执行结果中可以看到:

SharedLibrary : libhello-jni.so

Install : libhello-jni.so => apps/hello-jni/project/libs/armeabi

生成了一个动态装载库libhello-jni.so,并且在libs/目录下NDK新建了一个armeabi文件夹,然后把libhello-jni.so放进去。

二、工程实践 – MyJni

1. NDK/apps/目录下新建一个文件夹:MyJni

2. MyJni下新建一个文件夹:project,用来存放实际工程

3. MyJni下新建一个文件:Application.mk, 内容如下:

APP_PROJECT_PATH := $(call my-dir)/project

APP_MODULES := Hello #最终.so文件的名字,如(Hello对应libHello.so

4.Eclipse中新建一个Android工程,Location选择上面的../apps/Myjni/project

5. 代码:

HelloJni.java

package com.jni.hello;

public class HelloJni {

public native String cmd(String c);

}

执行javac HelloJni.java -> javah HelloJni,生成HelloJni.h文件, 内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class HelloJni */

#ifndef _Included_ HelloJni

#define _Included_HelloJni

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: HelloJni

* Method: cmd

* Signature: (Ljava/lang/String;)Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_ HelloJni_cmd

(JNIEnv *, jobject, jstring);

#ifdef __cplusplus

}

#endif

#endif

注意几个地方jstringLjava/lang/String;

CJava之间传递数据时,应该知道彼此之间的对应类型。如jstring 对应Ljava/lang/String;

6. project/目录下新建一个文件夹:jni,用来存放C/C++文件,把上面的HelloJni.h放进去。

7. 实现HelloJni.c

#include “HelloJni.h”

JNIEXPORT jstring JNICALL Java_HelloJni_cmd(JNIEnv * env, jobject obj, jstring cmd)

{

//略,参考附件源代码

}

8. jni目录下新建一个Android.mk, 内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := Hello #最终.so文件的名字,如(Hello对应libHello.so

LOCAL_SRC_FILES := HelloJni.c

LOCAL_LDLIBS += -llog

include $(BUILD_SHARED_LIBRARY)

9. Cygwin编译生成动态装载库

打开Cygwincd进入NDK目录,如/cygdrive/e/eclipse/android-ndk-1.6_r1

执行make APP=MyJin,如图:

生成了libHello.so,并被放到../libs/armeabi目录下。

10. Android工程中调用JNI,如下Hello.java 代码片段:

public class Hello extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//…

System.loadLibrary("Hello"); //对应libHello.so

HelloJni hjni = new HelloJni();

String cmd = “cat /proc/meminfo”; //shell 命令,查看内存信息

_tv.setText("excute " + cmd + "\n" + hjni.cmd(cmd)); //在界面上显示执行结果

setContentView(_tv);

}

}

11. 模拟器运行结果:

12.源代码及工具包

参考附件。

一、

二、

三、 总结/问题

本文档是Android工程使用JNI之实践的初级篇,许多地方都是按部就班,比较死板。像

下面的一些问题都没有做深入的研究。

1. 为什么一定要把工程放在NDK/apps/下?

2. 如果工程的目录结构变化了,该如何写Application.mkAndroid.mk?

能否将CygwinNDK都“集成”到Eclipse中,实现一键编译?

更多相关文章

  1. Android(安卓)Ant Build简单总结
  2. android 导入工程报错:Unable to resolve target 'android-9'
  3. 安装APK文件到Android模拟器
  4. android 高级工程师成长之路(Android高手应该精通哪些内容?)
  5. Android中AsyncTask的简单用法
  6. android 引用类库工程编译时报错
  7. Unity调用Android配置方法
  8. Unity编译Android的原理解析和apk打包分析
  9. Android——修改开机画面

随机推荐

  1. 优化博客页面访问速度
  2. ThreadLocal就是这么简单
  3. 迁到HTTPS这么麻烦,为什么还要折腾?
  4. 科班出生与自学的程序员,哪个强?
  5. 帆软报表自定义函数-取json数据
  6. 理想中的职业自由,却不那么理想
  7. Python之父-Guido van Rossum
  8. 不会CSS的痛
  9. C语言复习(一)
  10. Mac版本的Sublime Text常用快捷键