`

Android NDK 入门

阅读更多
前言
Android系统中的应用程序都是用Java开发的。Android NDK使我们能够在android上使用C/C++开发的原生代码。有两个理由使用NDK: 一是合理的重用现有的代码;二是在程序中某些关键的部分提高执行效率。
这里先讲几个符号的约定:
<project> - 你的Android应用程序工程的目录
<ndk> - 你的ndk安装的目录

捷径
这里先扯一句题外话 -- 如果你不需要使用NDK开发,只是需要使用第三方用NDK开发的库,那么你只需要这样做:
把第三方提供的libxxx.so放到你的<project>/libs/armeabi/下, 然后在程序随便什么地方中加入
static {
    System.loadLibray("xxx");
}
就可以使用该库了。

安装NDK
NDK的安装很简单:
1. 首先要将SDK升级至最新,然后下载ndk(可能要fanqiang,恩恩)将它解压到某个目录<ndk>下。
2. 运行: <ndk>/build/host-setup.sh
3. 如果成功的话就OK了,如果失败的话检查一下你是不是下载了正确的ndk版本(例如你的操作系统是linux而下载了windows版的ndk).

Java部分
现在我们用一个很简单的例子来说明NDK的使用。我们在eclipse中新建一个android工程,其中:
Project Name:jnitest
Build Target: Android 1.6
Application Name: JNI Test
Package Name: org.eshock.jnitest
Create Activity: JNITest

JNITest.java:

--------------------------------------------------------------------------------
package org.eshock.jnitest;

import android.app.Activity;
import android.os.Bundle;

public class JNITest extends Activity {
   public native int plus (int x, int y);
  
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int x = plus(1, 2);
        android.util.Log.d("jni", String.valueOf(x));
    }
  
    static {
       System.loadLibrary("mylib");
    }
}

--------------------------------------------------------------------------------
我们只是演示NDK,所以就不要界面了。在这个程序中,我们调用一个c语言编写的plus(int, int)函数来计算1+2的值,然后在log中打印它。这个库的名称叫做mylib。
要使用一个c语言的函数,需要在java中声明:
public native int plus(int x, int y);
这样java编译器就知道这个函数是外部库中实现的。

C部分

接下来我们使用C语言实现这个plus函数。
创建<project>/jni/mylib.c:

--------------------------------------------------------------------------------
#include <string.h>
#include <jni.h>

JNIEXPORT jint JNICALL
Java_org_eshock_jnitest_JNITest_plus( JNIEnv* env,
                                                  jobject thiz,
                                                  jint x,
                                                  jint y )
{
    return x + y;
}

--------------------------------------------------------------------------------
这里我们看到,mylib.c里的plus函数比java里面的plus函数的签名要复杂了很多,主要是plus前面增加了包名,函数中多了两个参数,以及所有的int变成了jint。关于c中类型与jni中类型的对应关系,可以参见jni的相关文档,例如core Java II中的最后一章。如果你不想去查阅文档,有一个方法:
首先随便在某个目录下创建一个文件JNITest.java:

--------------------------------------------------------------------------------
public class JNITest {
    public native int plus (int x, int y);
}

--------------------------------------------------------------------------------
然后在命令行下执行:
javac JNITest.java && javah JNITest
将生成一个文件JNITest.h:

--------------------------------------------------------------------------------
/* 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:    plus
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_JNITest_plus
(JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

--------------------------------------------------------------------------------
这里自动生成了java中native函数对应的签名,你可以在c代码中使用它。(记得修改包名)。

Android.mk和Application.mk
Android.mk是一个makefile,用来告诉NDK需要编译哪些文件,生成哪些模块。我们创建<jni>/Android.mk文件:

--------------------------------------------------------------------------------
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := mylib
LOCAL_SRC_FILES := mylib.c

include $(BUILD_SHARED_LIBRARY)

--------------------------------------------------------------------------------
其中LOCAL_PATH表示c源代码文件的位置;LOCAL_MODULE表示生成的共享库的名称;LOCAL_SRC_FILES代表c代码的文件。不需要把头文件列在里面;头文件的依赖关系是ndk自动计算的。

Application.mk的作用是告诉Android SDK需要哪些库文件。有了它,NDK就可以把库放在正确的位置。我们创建<project>/Application.mk:

--------------------------------------------------------------------------------
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES      := mylib

--------------------------------------------------------------------------------
APP_PROJECT_PATH代表android工程所在目录,在本例中它被放在<project>中; APP_MODULES表示工程需要的库,如果有多个以空格分开。

编译共享库
由于ndk规定Application.mk必须放在<ndk>/apps/project_name,我们在<ndk>下创建一个符号连接:
ln -s <project> <ndk>/apps/jnitest
这样,我们就可以开始编译共享库了:
在<ndk>目录下运行:
make APP=jnitest

--------------------------------------------------------------------------------
Android NDK: Building for application 'jnitest'
Compile thumb : mylib <= apps/jnitest/jni/mylib.c
SharedLibrary : libmylib.so
Install        : libmylib.so => apps/jnitest/libs/armeabi

--------------------------------------------------------------------------------
可以看到编译成功,并在<project>/libs/armeabi/下生成了libmylib.so。

测试
在运行之前,首先确认一下你的工程里面各个文件都齐全,应该类似于这样:


然后测试,正常的话应该能看到log中有输出3.

  • 大小: 31.8 KB
分享到:
评论

相关推荐

    androidndk入门.pdf

    我们的项目有一个叫做“com.mamlambo.sample.ndk1”的包,带有一个叫做“AndroidNDK1SampleActivity”的默认 Activity。在项目的顶层创建一个叫做“jni”的目录,这是您放置原生代码的地方。 第 3 步:添加一些 C ...

    AndroidNDK入门项目实战

    本资源提供了一个Android NDK入门项目实战,通过实例帮助初学者理解和掌握NDK的使用。 ### 1. NDK基础知识 - **NDK的用途**:主要用在需要高效计算或使用C/C++库的场景,如音频视频处理、游戏开发、加密算法等。 -...

    Android NDK入门

    在文件列表中提到的`hello-jni`是一个典型的NDK入门示例。它通常包含一个简单的Java类,声明了一个`native`方法,以及对应的C/C++源代码,演示了如何使用JNI进行基本的交互。这个例子可以帮助你快速了解NDK的基本...

    android NDK 入门例子

    这个"android NDK 入门例子"很可能是为了帮助初学者理解和掌握NDK的基本用法。NDK的主要用途是提高性能、利用硬件加速、以及复用已有的C/C++库。 首先,安装Android NDK是入门的第一步。通常,你可以通过Android ...

    android NDK 入门项目 实战 详细文档

    压缩包中的“史上最强NDK入门项目实战.doc”很可能是详细的教程文档,包含每个步骤的指导和解释;“sources”可能包含了示例项目的源代码;“apps”可能是一些示例应用,用来展示NDK的使用;“myjni”可能是一个特定...

    android NDK入门篇----混合使用java和c/c++代码 源码工程

    本项目是一个关于Android NDK入门的实例,展示了如何混合使用Java和C/C++代码。我们将深入探讨这个主题,了解其关键概念、步骤以及实际应用。 首先,NDK的主要目的是为Android应用提供原生代码支持。原生代码通常比...

    Android NDK入门 实例 详解

    ### NDK实例:Android史上最强NDK入门项目实战 这个项目实战可能包括以下内容: 1. **Hello, World!**:编写一个简单的原生库,实现Java调用并打印"Hello, World!"。 2. **计算示例**:使用C/C++进行数学计算,...

    androidndk开发实战

    最后,“Android NDK入门进阶文档”是一个综合性的学习资料,可能包含了NDK的基本概念,如本地模块创建,CMake或ndk-build的使用,以及更高级的主题,如多线程编程、内存管理、性能优化等。这部分内容对于初学者和有...

    Android NDK入门,C与Java的互相调用Demo

    本示例将带你入门Android NDK,并展示如何通过JNI(Java Native Interface)实现C语言与Java代码的互相调用。 首先,理解JNI是关键。JNI是Java平台的一部分,它为Java代码提供了与本地代码交互的能力。在Android中...

    学习Android_NDK入门很简单

    《学习Android NDK入门很简单》这篇教程主要针对想要掌握Android NDK开发的初学者,旨在指导如何入门并开始使用NDK。NDK是Android开发中的一个重要工具,它允许开发者使用C/C++原生代码来编写部分应用,尤其适用于...

    Android_ NDK编程入门笔记

    #### 二、Android NDK入门学习过程 ##### 1. 开发环境的搭建 - **Linux环境**:由于需要生成能在ARM架构设备上运行的.so动态链接库文件,这通常需要通过交叉编译来实现,而交叉编译器通常在Linux环境下更为成熟...

    androidndk环境搭建和入门教程

    最后,“Android NDK入门进阶文档”将帮助你深入理解NDK的高级用法,比如多线程编程、内存管理、动态库加载等。这些进阶主题能让你更好地发挥NDK的优势,编写出更高效、更稳定的原生代码。 总之,Android NDK为...

    Android NDK 开发入门例子

    **Android NDK 开发入门详解** Android NDK(Native Development Kit)是Google提供的一款用于在Android平台上进行原生代码开发的工具集。它允许开发者使用C++和其他本地语言编写部分应用,以实现高性能计算或者...

    Android ndk jni 史上最强NDK入门项目实战

    《Android NDK与JNI实战:史上最详尽的NDK入门指南》 在移动开发领域,Android NDK(Native Development Kit)和JNI(Java Native Interface)是开发者用来实现高性能计算、利用硬件加速或调用C/C++库的重要工具。...

    Android NDK Beginner‘s Guide

    1. **第1章:Android NDK入门** - **安装配置**:详细介绍如何在开发环境中安装配置Android NDK,包括环境变量设置等步骤。 - **第一个NDK项目**:通过一个简单的示例项目,展示如何创建和编译第一个使用NDK的...

    android ndk tutorial

    - [Android NDK 开发入门](http://mobile.51cto.com/android-225364.htm) - [使用 Android NDK 开发应用程序](http://blog.chinaunix.net/u2/84258/showart.php?id=2289703) - [简单的 Android NDK 教程]...

    Android NDK开发轻松入门.pdf

    ### Android NDK 开发轻松入门知识点详解 #### 一、Android NDK 概述 **Android NDK**(Native Development Kit)是 Android SDK 的一个重要组成部分,它为开发者提供了使用 C 或 C++ 编写应用程序的功能,使...

Global site tag (gtag.js) - Google Analytics