当前位置:操作系统 > 安卓/Android >>

[Android应用开发]-(14)JNI----经典实例分析

    接下来几篇文章,学习JNI开发,主要是学习《JNI详解》,将里面的实例通过Android平台实现,首先由一个经典实例引出 – HelloWorld!!HelloWorld是经典的,一想起学编程,就想起那些年我们一起写过的HelloWorld。这里用HelloWorld来讲解JNI的开发过程。这个过程大致可通过下图来说明:

\
1)  新建一个HelloWorld工程;

2)  创建一个带有native方法的类Helloworld.java;


[java]
package org.winplus.helloworld; 
public class HelloWorld { 
    public native void print();      
    private void stitic() { 
        System.loadLibrary("helloworld"); 
    } 

package org.winplus.helloworld;
public class HelloWorld {
 public native void print();   
 private void stitic() {
  System.loadLibrary("helloworld");
 }
}
HelloWorld类首先声明了一个publicnativevoid print()方法。Static包含的是本地库。在java代码中声明为native的本地方法只作为声明存在。在调用本地方法之前,必须先装载含有该方法的本地库,如HelloWorld中所示,置于static中,在JavaVM初始化一个类时,首先会执行这段代码,这可保证调用本地方法之前装载了本地库。转载的机制请看后文…

3)  使用javac编译Helloworld.java

使用Eclipse的同学不需要做此动作,都自动编译了。进入Class目录。

4) 使用javah –jni 编译Helloworld.class 生成头文件 Helloworld.h;Javah –jni org.winplus.helloworld.HelloWorld会生成一个名为:org_winplus_helloworld_ HelloWorld.h的头文件。生成的代码如下:

[cpp]
<SPAN style="FONT-SIZE: 16px">/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h>  
/* Header for class org_winplus_helloworld_HelloWorld */ 
 
#ifndef _Included_org_winplus_helloworld_HelloWorld  
#define _Included_org_winplus_helloworld_HelloWorld  
#ifdef __cplusplus  
extern "C" { 
#endif  
/*
 * Class:     org_winplus_helloworld_HelloWorld
 * Method:    print
 * Signature: ()V
 */ 
JNIEXPORT void JNICALL Java_org_winplus_helloworld_HelloWorld_print 
  (JNIEnv *, jobject); 
 
#ifdef __cplusplus  

#endif  
#endif</SPAN> 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_winplus_helloworld_HelloWorld */

#ifndef _Included_org_winplus_helloworld_HelloWorld
#define _Included_org_winplus_helloworld_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     org_winplus_helloworld_HelloWorld
 * Method:    print
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_org_winplus_helloworld_HelloWorld_print
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
我们注意到JNIEXPORTvoid JNICALL Java_org_winplus_helloworld_HelloWorld_print(JNIEnv *,jobject);这里我们注意到JNIEXPORT和JNICALL两个宏,我们看到这个函数声明接收两个参数而对应的Java代码中并没有参数。第一个参数是指向JNIEnv结构的指针;第二个参数,为HelloWorld对象自身,即this指针。
5) 使用C实现头文件中的函数


[cpp]
<SPAN style="FONT-SIZE: 16px">#include <jni.h> 
#include <stdio.h>  
#include "android/log.h"  
#include "HelloWorld.h"  
static const char *TAG="HelloWorld"; 
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)  
JNIEXPORT void JNICALL Java_org_winplus_helloworld_HelloWorld_print 
  (JNIEnv *env, jobject obj){ 
    LOGI("Hello World"); 
    return;   

</SPAN> 

#include <jni.h>
#include <stdio.h>
#include "android/log.h"
#include "HelloWorld.h"
static const char *TAG="HelloWorld";
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
JNIEXPORT void JNICALL Java_org_winplus_helloworld_HelloWorld_print
  (JNIEnv *env, jobject obj){
 LOGI("Hello World");
 return; 
}

这里为了方便看到打印信息,使用了jni中的log.h头文件和ANDROID_LOG_INFO宏。

6)  编译C文件生成本地库。这一步比较繁琐,请下载源码看吧。具体步骤

a)      将头文件及C文件拷贝到jni目录,并编写Android.mk和Application.mk文件

b)      通过ndk或者在Ubuntu下编译,生成helloworld.so文件  www.zzzyk.com

c)      将生成的文件拷贝到libs/armeabi目录下,并更改名字为:libhelloworld.so

7)  运行程序,查看结果。

 \
作者:tangcheng_ok
 

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,