读书人

开发基于C++/C资源库的Android程序方法

发布时间: 2013-10-12 11:54:02 作者: rapoo

开发基于C++/C资源库的Android程序步骤

因为Android程序是用java写的,跑在Dalvik JVM上,而在某些情况下必须要使用到用C++或者C写的代码库,那么就要用ndk开发包来编译这些原生文件,然后才能调用。下文中会提到几个名词:JNI,NDK,Cygwin以及Eclipse工程。

JNI简介

JNI全称为Java Native Interface(JAVA本地调用)。从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&C++)进行交互。并非从Android发布才引入JNI的概念的。


JNI与NDK

简单来说,Android的NDK提供了一些交叉编译工具链和Android自带的库,这些Android的库可以让开发者在编写本地语言的程序时调用。而NDK提供的交叉编译工具链就对已经编写好的C&C++代码进行编译,生成库。

当然了,你也可以自己搭建交叉编译环境,而不用NDK的工具和库。然后生成库,只要规范操作,一样可以生成能让JAVA层成功调用的库文件的。


Cygwin简介

cygwin可以模拟一个windows上的Linux环境。

安装cygwin的时候,默认为在线安装,注意要确保安装了make包,这个很重要,不然后面编译原生代码的时候会出现can't find make类似的错误在cygwin里面。

当出现Select Packages对话框时,搜索“devel”,为了以防万一,把安装选项“default”更改为“install”,安装所以必须的编译工具。然后进入漫长的下载状态,差不多一两个小时,接下来的步骤默认就行。

开发基于C++/C资源库的Android程序方法
安装完cygwin后,去到其安装目录,可以发现有一个“home”目录,里面有一个“当前windows用户名”的文件夹,就相当于linux系统下面的/home/userName了。然后把Android NDK(windows版本)安装到home目录下的那个“当前windows用户名”文件夹中。

在home目录下的那个“当前windows用户名下,用文本编辑器打开“.bash_profile”文件,在后面加入如下配置信息

[java] view plaincopy
  1. ndk=/home/Administrator/android-ndk-r7b
  2. export $ndk

打开cygwin,执行

[java] view plaincopy
  1. cd $ndk
会自动跳转到该ndk目录下。
然后在ndk目录下建立c程序

新建一个目录,命名为HelloWorld,然后在里面新建一个名为jni的目录(名称一定要是jni,因为ndk-build的时候会在HelloWorld目录下寻找jni的目录,然后进行build),在jni目录下新建如下文件HelloWorld.c和Android.mk。

HelloWorld.c文件代码如下(此JNI是没有jni_onLoad函数的)

[java] view plaincopy
  1. #include <string.h>
  2. #include <jni.h>
  3. jstring
  4. Java_com_conowen_helloworld_HelloWorldActivity_helloWorldFromJNI( JNIEnv* env,
  5. jobject thiz )
  6. {
  7. return (*env)->NewStringUTF(env, "HelloWorld! I am from JNI !");
  8. }
  9. /*注意,这里
  10. jstring 表示返回值
  11. Java_com_conowen_helloworld_HelloWorldActivity_helloWorldFromJNI
  12. 写法是Java+Android工程的包名+Android工程的Activity名+方法名,点号用下划线表示,这个写法很严格。
  13. 包名:com_conowen_helloworld
  14. Activity名:HelloWorldActivity
  15. 方法名:helloWorldFromJNI
  16. JNIEnv* env, jobject thiz是Native方法自带的参数,可以用来转换一个数据类型。也就是说其实这个helloWorldFromJNI是没有形参的。
  17. */

Android.mk代码如下

关于Android.mk的编写格式,下一篇博文补全

[java] view plaincopy
  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. #LOCAL_MODULE表示生成的库的名字,前面的lib和后缀名不用写
  4. LOCAL_MODULE := HelloWorld
  5. LOCAL_SRC_FILES := HelloWorld.c
  6. include $(BUILD_SHARED_LIBRARY)

然后在终端里面,转到HelloWorld目录下,执行

[java] view plaincopy
  1. $ndk/ndk-build
$ndk是之前配置的NDK环境变量。编译成功后,会在在目录生成libs和obj两个文件夹,libs里面有刚刚编译成的libHelloWorld.so库。


5、新建一个Android工程

在eclipse里面新建一个Android工程,java代码如下,然后把刚刚生成的libs文件夹拖到Android工程目录下。

[java] view plaincopy
  1. package com.conowen.helloworld;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.widget.TextView;
  5. public class HelloWorldActivity extends Activity {
  6. /** Called when the activity is first created. */
  7. @Override
  8. public void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. TextView tv = new TextView(this);
  11. tv.setText(helloWorldFromJNI());
  12. setContentView(tv);
  13. }
  14. public native String helloWorldFromJNI();// native声明,表示这个方法来自Native层。实现过程已经在native层实现了
  15. static {
  16. System.loadLibrary("HelloWorld");// 加载库,前面的lib和,后缀名不用写
  17. }
  18. }
应该可以跑起来了。

读书人网 >C++

热点推荐