`
meohao
  • 浏览: 97812 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

写在20110626:NDK、JNI

 
阅读更多
    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将它解压到某个目录<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.
分享到:
评论

相关推荐

    NDK JNI的学习

    在Android环境中,JNI通常是通过NDK来实现的,使得开发者能够编写高性能的模块,如图形处理、物理模拟或者加密算法等。 1. **NDK的使用场景** - 高性能计算:对于需要大量计算的任务,如游戏引擎、图像处理、音频...

    Android NDK JNI 经典实例

    Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例

    Android NDK JNI 开发

    Android NDK JNI 开发是移动应用开发中的一个重要领域,它允许开发者使用C++和其他原生语言来编写部分Android应用程序,从而提升性能、利用硬件加速以及复用现有的C/C++库。JNI(Java Native Interface)是Java平台...

    android ndk jni demo source code

    这个"android ndk jni demo source code"是针对这一主题的一个示例项目,它已经通过了测试,因此我们可以从中学习到如何在实际项目中有效地使用JNI技术。 JNI(Java Native Interface)是Java平台的标准接口,它...

    NDK JNI开发例子代码2

    本示例代码"NDK JNI开发例子代码2"将深入探讨如何在Android应用中使用NDK和JNI进行原生编程。 首先,我们需要理解NDK的作用。在Android应用中,主要的编程语言是Java,但有时为了优化性能,如图形处理、数学计算或...

    ndk jni实例源码

    在Android开发中,NDK(Native Development Kit)和JNI(Java Native Interface)是两个非常重要的概念,它们允许开发者使用C/C++等原生代码来编写部分应用,从而提高性能、优化计算密集型任务或者利用已有的C/C++库...

    NDK jni中编程时帮助文档

    在移动开发领域,Android NDK(Native Development Kit)和JNI(Java Native Interface)是至关重要的工具,它们允许开发者使用C++或其他原生语言编写高性能的代码,与Java应用程序交互。NDK提供了一个平台,使得...

    Android Studio NDK JNI配置Demo代码 2016

    本Demo代码主要展示了如何在Android Studio中配置NDK和JNI,以便在Android应用中使用本地库。 首先,我们需要了解NDK的基本概念。NDK是一套工具集,允许开发者在Android应用中使用C和C++代码,这可以提高性能,尤其...

    NDK JNI开发例子代码

    这个"NDK JNI开发例子代码"是一个实际的项目实例,帮助开发者了解如何在Android中使用NDK和JNI。通过参考提供的博客链接(http://blog.csdn.net/lm1391058/article/details/51221823),我们可以学习到以下关键知识...

    jni开发demo:通过jni将一张彩色图片转换为黑白图片

    JNI(Java Native Interface)是Java平台提供的一种标准接口,它允许Java代码和其他语言写的代码进行交互。在Android系统中,JNI被广泛应用于性能优化、调用底层库、访问硬件设备等场景。本示例"jni开发demo:通过...

    android NDK JNI 中文 资料 文档

    总之,这份“Android NDK JNI 中文 资料 文档”应当提供了从基础知识到实际操作的全面指南,帮助开发者深入理解如何在Android平台上利用NDK和JNI进行原生编程,提升应用性能和功能。通过学习和实践,开发者可以掌握...

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

    在移动开发领域,Android NDK(Native Development Kit)和JNI(Java Native Interface)是开发者用来实现高性能计算、利用硬件加速或调用C/C++库的重要工具。本指南将深入浅出地介绍这两个概念,通过实际项目实战,...

    android ndk jni so库生成

    在Android开发中,JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。NDK(Native Development Kit)是Google提供的一套工具集,用于让开发者在Android应用中使用C/C++...

    Eclipse Android NDK JNI 详细开发流程

    在进行Android应用开发时,有时我们需要利用原生代码(通常是C/C++)来提高应用性能或访问某些特定硬件资源,这时就需要用到NDK(Native Development Kit)与JNI(Java Native Interface)。本文将详细介绍如何在...

    Android NDK+JNI 练习1

    在Android开发中,NDK(Native Development Kit)和JNI(Java Native Interface)是两个关键工具,它们允许开发者在Android应用中使用C/C++代码。这个"Android NDK+JNI 练习1"很可能是为了帮助开发者熟悉如何在本地C...

    JNI完全技术手册 带完整书签

    3、实例三、在jni函数中访问java类中的对象实例域... 58 4、实例四:在jni函数中访问类的静态实例域... 60 5、实例五:在jni函数中调用java对象的方法... 60 6、实例六:在jni函数中调用java类的静态方法... 61 ...

    AndroidStudio环境下的jni调用(NDK)

    AndroidStudio环境下的jni调用(NDK),这个教程可以让完全不会AndroidStudio的人学会jni调用。完全步骤话,非常简单。

    Ndk-Jni开发实战

    在Android应用开发中,NDK(Native Development Kit)和JNI(Java Native Interface)是两个重要的技术,用于实现Java代码与本地C/C++代码的交互。本实战教程将深入探讨NDK-JNI的开发过程,结合具体的AES加密DEMO,...

    Android NDK编写之JNI规范升级版

    在Android开发中,NDK(Native Development Kit)和JNI(Java Native Interface)是两个关键工具,它们允许开发者使用C++或者其他本地语言编写部分代码,从而提高应用的性能或实现特定功能。本文将深入探讨Android ...

Global site tag (gtag.js) - Google Analytics