`
zhubin215130
  • 浏览: 142314 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【转】Android JNI实例

阅读更多

AndroidSDK中没有包括JNI的支持,而且对如何支持JNI也没有任何文档说明。不过既然整个Android平台是开源的,我们可以通过Google发布的源代码来找到一些线索(比如frameworks/base/media/jni/目录),依葫芦画瓢的实现上层JAVA程序通过JNI来调用Native C程序中的函数。

 

依照下面的步骤可以实现一个非常简单的JNI的实例程序:

 

1  首先编写C模块,实现动态库。(关于如何在Android中编译C模块的更多细节,请参考《Android编译环境(1) - 编译Native C的helloworld模块》。)

development目录下添加新目录hellolib,并添加hellolib.cAndroid.mk文件。hellolib.c的内容如下:

#include <jni.h>

 

#define LOG_TAG "TestLib"

#undef LOG

#include <utils/Log.h>

 

 

JNIEXPORT void JNICALL Java_com_test_TestHelloLib_printHello(JNIEnv * env, jobject jobj)

{

    LOGD("Hello LIB!\n");

}

注意这里的函数名需要按照JNI的规范(因此也可以用javah -jni工具来生成头文件,来保证函数名的正确性),Java_com_test_TestHelloLib_printHello的命名对应后面在java代码中,package名字是com.test,类名是TestHelloLibnative函数名是printHello

另外,LOGD#define LOG_TAG "TestLib"等打印log的方式是采用了Android所提供的LOG机制,这样才能通过Androidlogcat工具看到log

用于编译C模块的Android.mk文件内容如下:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

 

LOCAL_SRC_FILES:= \

    hellolib.c

 

LOCAL_C_INCLUDES := \

    $(JNI_H_INCLUDE)

 

LOCAL_SHARED_LIBRARIES := \

    libutils

 

LOCAL_PRELINK_MODULE := false

 

LOCAL_MODULE := libhello

 

include $(BUILD_SHARED_LIBRARY)

该文件中的一些变量分别对应的含义如下:

LOCAL_SRC_FILES  编译的源文件

LOCAL_C_INCLUDES  需要包含的头文件目录

LOCAL_SHARED_LIBRARIES  链接时需要的外部库

LOCAL_PRELINK_MODULE  是否需要prelink处理(参考prelink的详细介绍:《动态库优化——Prelink(预连接)技术》,AndroidToolchain, prelink工具:《Android Toolchain与Bionic Libc》)

LOCAL_MODULE  编译的目标对象

BUILD_SHARED_LIBRARY  指明要编译成动态库。

       接下来回到Android顶层目录,并执行make libhello来编译:

# cd $(YOUR_ANDROID) && make libhello

target thumb C: libhello <= development/hellolib/hellolib.c

target SharedLib: libhello (out/target/product/generic/obj/SHARED_LIBRARIES/libhello_intermediates/LINKED/libhello.so)

target Non-prelinked: libhello (out/target/product/generic/symbols/system/lib/libhello.so)

target Strip: libhello (out/target/product/generic/obj/lib/libhello.so)

Install: out/target/product/generic/system/lib/libhello.so

       编译结果可得到位于out/target/product/generic/system/lib/目录的动态共享库libhello.so

 

2.编写Java模块,来通过JNI方式调用C接口。具体Eclipse环境的搭建请参考Android SDK文档中的详细说明,及Hello Android程序的创建过程,这里仅给出我们需要修改的TestHelloLib.java文件:

package com.test;

 

import android.app.Activity;

import android.os.Bundle;

 

public class TestHelloLib extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        printHello();

    }

   

    static {

    System.loadLibrary("hello");

    }

   

    private native void printHello();

}

注意上面代码中粗体字部分:private native void printHello()用来声明一个native接口,static { System.loadLibrary("hello"); } 用来加载上面步骤中生成libhello.so(注意loadLibrary方法的参数不是”libhello.so”,而是去掉前缀和后缀之后的”hello”),onCreate()方法中则调用了printHello()接口。

    通过这一步骤可生成Android开发者所熟悉的apk文件:TestHelloLib.apk

 

3.集成测试TestHelloLib.apklibhello.so。先运行emulator并将TestHelloLib.apklibhello.so上传至emulator中。注意要将libhello.so上传到emulator/system/lib目录,由于该目录是只读的,上传之前先要执行adb remount

# adb remount

# adb push out/target/product/generic/system/lib/libhello.so /system/lib

# adb install TestHelloLib.apk

       接下来在模拟器菜单中可以看到已经安装的TestHelloLib程序,运行即可。

       由于JNI接口printHello()并没有作界面上的改动,要验证其效果需要用Androidlogcat工具来查看。运行”adb logcat”可以找到下面的log片断:

I/ActivityManager(   48): Starting activity: Intent { action=android.intent.action.MAIN categories={android.intent.category.LAUNCHER} flags=0x10200000 comp={com.test/com.test.TestHelloLib} }

I/ActivityManager(   48): Start proc com.test for activity com.test/.TestHelloLib: pid=174 uid=10024 gids={}

D/dalvikvm(  174): Trying to load lib /system/lib/libhello.so 0x43481c58

D/dalvikvm(  174): Added shared lib /system/lib/libhello.so 0x43481c58

D/dalvikvm(  174): No JNI_OnLoad found in /system/lib/libhello.so 0x43481c58

D/dalvikvm(  174): +++ not scanning '/system/lib/libwebcore.so' for 'printHello' (wrong CL)

D/dalvikvm(  174): +++ not scanning '/system/lib/libmedia_jni.so' for 'printHello' (wrong CL)

D/TestLib (  174): Hello LIB!

I/ActivityManager(   48): Displayed activity com.test/.TestHelloLib: 806 ms

       这里包含了调用printHello()接口的log信息,其中D/TestLib (  174): Hello LIB!”就是printHello()所打印的信息。至此成功完成Android 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 JNI实例01

    在这个“Android JNI实例01”中,我们将探讨如何使用JNI在Android应用中集成C/C++代码,以及如何在ARM架构的设备上运行这些本地代码。 1. **JNI基础**: - JNI接口定义了一系列函数,如`FindClass`, `GetMethodID`...

    Android jni 编程实例

    在这个"Android jni 编程实例"中,我们将探讨如何在Android Studio环境下进行JNI开发,通过一个简单的入门demo来学习这个过程。 首先,我们需要了解JNI的基本概念。JNI是Java平台提供的一种接口,它允许Java代码...

    Android JNI 实例

    总的来说,Android JNI实例涵盖了从Java到C/C++的调用过程,涉及了JNI的基本原理和实践技巧。无论是静态注册还是动态注册,都需要理解JNI的核心概念,如JNI函数的调用约定、JNI数据类型以及Java对象在本地代码中的...

    android调用jni实例

    我们将以"android调用JNI实例"为例,一步步解释这个过程。 首先,我们需要准备开发环境。安装Android NDK是必不可少的步骤,NDK(Native Development Kit)是一组工具,开发者可以使用它来编写用C和C++编写的本地...

    android JNI学习三实例

    在这个"android JNI学习三实例"中,我们将深入探讨如何在Android应用开发中使用JNI。 一、JNI简介 JNI是Java平台的一部分,提供了一套接口,让Java代码能够调用本地(native)代码,同时也允许本地代码调用Java对象...

    serial_jni_largestgle_Androidjni_Android串口操作JNI代码_android_

    总结来说,`serial_jni_largestgle_Androidjni_Android串口操作JNI代码_android_`项目是一个Android应用使用JNI进行串口通信的实例。它涵盖了JNI编程、Android NDK开发、原生代码与Java代码的交互、串口通信协议以及...

    Android jni 实例

    总结来说,Android JNI实例主要涉及以下几个关键点: 1. 在Java层声明native方法。 2. 使用`javah`或Android Studio生成头文件。 3. 编写C/C++代码实现头文件中的方法。 4. 配置CMake或NDK构建系统生成.so库文件。 5...

    Android JNI应用实例

    在"Android JNI应用实例"中,我们可以深入学习如何使用JNI。通常,一个简单的JNI开发流程包括以下步骤: 1. 创建Java类:首先,我们需要在Java层定义一个类,声明native方法,这些方法将在C/C++代码中实现。 2. ...

    android jni实用demo

    Android JNI(Java Native Interface)是Android系统中连接Java层与C/C++原生代码的关键技术。这个"android jni实用demo"提供了一个很好的学习平台,帮助开发者深入理解如何在Android应用中使用JNI进行跨语言编程。 ...

    Android JNI实例

    在这个“Android JNI实例”中,我们将深入探讨Android NDK开发的相关知识。 首先,我们要理解Android NDK(Native Development Kit)。NDK是一组工具,开发者可以使用它来编写部分应用的原生代码,这些代码可以在...

    Android JNI多线程编程回调JAVA函数

    在Android开发中,JNI(Java Native Interface)是一个关键的技术,它允许Java代码和其他语言写的代码进行交互。JNI在处理性能敏感的任务,如图形渲染、硬件访问或者与C/C++库集成时,尤其有用。本话题将深入探讨如何...

    android_JNI实例

    Android JNI(Java Native Interface)是Android系统中用于Java与本地代码(C/C++)交互的框架。它允许开发者在Android应用中使用C/C++代码,从而利用这些语言的高性能、低级内存管理以及对硬件的直接访问能力。JNI...

    android驱动JNI的USB2串口的参考实例

    "android驱动JNI的USB2串口的参考实例"是一个关于如何在Android系统中利用JNI(Java Native Interface)技术来实现USB到串口通信的实践案例,主要涉及到FTDI(Future Technology Devices International)公司的FT23X...

    Android Jni调用实例

    在Android Jni调用实例中,我们通常会经历以下几个步骤: 1. **创建本地方法声明**:在Java层,我们需要声明一个native方法,该方法将在C/C++代码中实现。例如: ```java public class NativeDemo { static { ...

    AndroidJNI实例

    AndroidJNI实例是一个深入理解并实践Java Native Interface (JNI)在Android平台上的应用示例。JNI是Java平台标准的一部分,允许Java代码和其他语言写的代码进行交互。这个实例将帮助开发者了解如何在Android应用中...

    android jni抛出异常

    在Android开发中,JNI(Java Native Interface)是一个关键的组件,它允许Java代码与其他语言(如C++或C)交互。JNI在许多场景下都非常有用,例如优化性能、调用系统库或者处理特定的硬件功能。然而,如同任何编程...

    Android JNI应用实例02

    Android JNI(Java Native Interface)是Android开发中的一个重要概念,它为Java代码提供了与本地C/C++代码交互的能力。...通过学习这个实例,开发者可以加深对Android JNI的理解,提高在实际项目中应用JNI的能力。

    android JNI调用实例

    本实例将深入探讨如何在Android应用中使用JNI。 1. **JNI简介** JNI是Java平台提供的一种接口,它使得Java代码可以调用本地(非Java)代码,同时也允许本地代码调用Java方法。这种混合编程模式为开发者提供了更大...

Global site tag (gtag.js) - Google Analytics