Linux下Eclipse使用NDK开发Android应用

本文介绍了如何使用Google提供的NDK开发Android应用,包括下载NDK、配置环境变量及Eclipse、添加本地支持、声明及实现C/C++接口等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Google提供的Android SDK 已经能够满足绝大多数场景下的Android应用开发,然而,在某些情况下,可能需要使用C/C++来开发应用程序或实现应用程序的部分功能,对此需求,google提供了NDK来满足开发人员的需要。

NDK(Native Development Kit)与SDK类似,是一套开发套件,它允许Android应用开发者嵌入从C、C++源代码文件编译来的本地机器代码到各自的应用软件包中,并通过JNI进行访问。Android从1.5开始支持NDK。在以下情况下可以考虑使用NDK:

1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。

2. 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。

3. 便于移植,用C/C++写的库可以方便在其他的嵌入式平台上再次使用。


目前在Eclipse下使用NDK开发Android应用的步骤已经相当简单,概括起来有以下步骤:

1. 下载NDK

官方下载路径:https://dl.google.com/android/ndk/android-ndk-r9d-linux-x86.tar.bz2 

目前NDK的最新版本是r9d,如果有新版本,只需修改上面地址中的版本号就可以

2. NDK环境变量配置

将下载完的android-ndk-r9d-linux-x86.tar.bz2 解压到你需要存放的路径后,使用vim或gedit等编辑器修改/etc/profile文件(sudo vim /etc/profile 或sudo gedit /etc/profile),在文件末尾加上如下两句:

export NDKROOT=/home/sprintwind/Android/android-ndk-r9d
export PATH=$NDKROOT:$PATH

其中,NDKROOT修改为你解压后的NDK文件夹路径

修改完之后reboot或在终端执行source /etc/profile 使之生效,然后执行ndk-build命令,出现类似如下打印说明环境变量配置成功:

Android NDK: Could not find application project directory !    
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.    
/home/sprintwind/Android/android-ndk-r9d/build/core/build-local.mk:148: *** Android NDK: Aborting    .  Stop.

3. 在Eclipse中配置NDK

首先,在Eclipse中配置NDK路径。配置方法:

Window->Preferences->Android->NDK, 然后点击NDK Location后面的Browse按钮选择NDK路径,这个路径应当与在环境变量中的配置是一致的,如下图所示:



选择完成之后点击OK按钮确认。

如果你的Eclipsee的Window->Preferences->Android下没有NDK这个选项,很可能是下载的ADT不完整,不包含NDK构建工具,可以重新下载ADT工具包解决

4.在项目中添加本地支持(Native Support)

Eclipse下在你的项目文件夹上右击,选择Android Tools->Add Native Support,在出现的对话框中输入你的lib库名称,一般取默认即可:


添加完成之后需要在Android项目中加载该库,需要在类中添加以下代码:

static{
    	System.loadLibrary("JNITest");
    }

这部分代码的意思是在Android应用运行之前先去加载libJNITest.so这个共享库,这样你的Android应用在运行过程中就可以调用你在 libJNITest.so中实现的接口了。其中System.loadLibrary()中传入的字符串 要和你在上面对话框中输入的名称一致。

5. 在Android项目的类中声明需要使用C/C++实现的接口

经过上面的步骤之后就可以在Android项目中声明需要使用C/C++实现的接口,由C/C++代码在加载的共享库中去实现了,为了简单起见,先声明以下接口:

public native String jniHelloWorld();

该接口返回一个String类型的对象,native修饰符表示该接口是一个本地方法,即在加载的共享库中实现。

6. 使用C/C++实现在Android项目中声明的接口

在第4步为项目添加了本地支持后,Eclipse会自动为项目生成一个jni文件夹,里面存放一份Android.mk文件和一份以输入的库名命名的cpp文件,我们需要实现的功能代码就可以在这个cpp文件中编写了。需要注意的是这个文件中的接口的声明和我们在Android项目中的声明是不一样的,java有一套相当复杂的接口规范来说明在cpp中应该怎么定义和java交互的C/C++接口,好在java还提供了javah这个命令为我们自动生成这个接口。javah命令的使用方法可以使用javah -h获得。

现在,问题来了,学挖掘机技术哪家强?嘿嘿,开个玩笑,步入正题:Android编译生成的class文件使用javah命令是不能正常工作的,需要重新编写个java文件,里面加上我们需要实现的接口声明,然后再利用javah文件来生成对应的.h文件。

可以编写如下java文件,文件名JniTest.java:

public class JniTest
{
        public native String jniHelloWorld();
}

保存后在这个java文件同级的目录下执行javac JniTest.java 命令编译生产.class文件, 然后再使用javah JniTest命令生成.h文件:


现在,.h文件已经生成好了,内容如下:

<span style="font-size:14px;">/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniTest */

#ifndef _Included_JniTest
#define _Included_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     JniTest
 * Method:    jniHelloWorld
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_JniTest_jniHelloWorld
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif</span>

其中

JNIEXPORT jstring JNICALL Java_JniTest_jniHelloWorld
  (JNIEnv *, jobject);</span>

就是需要我们用C/C++实现的接口,可以将此接口拷贝到Eclipse项目中jni文件夹下的.cpp文件中,修改包名和类名为Android项目的,然后就可以编写C/C++代码来实现功能了,先实现个简单的功能吧:

#include <jni.h>


#ifdef __cplusplus
extern "C" {
#endif


JNIEXPORT jstring JNICALL Java_com_sprintwind_jnitest_MainActivity_jniHelloWorld
  (JNIEnv *env, jobject obj)
{
<span style="white-space:pre">	</span>return env->NewStringUTF("Hello World From JNI!");
}


#ifdef __cplusplus
}
#endif


以上接口中,com_sprintwind_jnitest是包名,MainActivity是声明了本地方法的类名。该接口返回一个java的String对象。这里还有需要注意的一点是,在本地接口前后一定要加上extern "C"的声明,否则会导致运行时出现找不到本地接口定义的错误。

接口实现完之后就可以在Android项目中调用了:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        tvHelloWorld = (TextView) findViewById(R.id.tvHelloWorld);
        tvHelloWorld.setText(jniHelloWorld());
    }

好了,大功告成,来看看效果吧:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值