Android JNI开发

我在网上看到的,感觉不错!

JNI在Android开发中使用的比较广泛,因为Android应用层是用Java实现,底层是c/c++实现的,所以应用层调用底层库时需要使用JNI。如果你熟悉java和c/c++的话,那么学习JNI主要需要掌握java和c/c++数据类型的转换、JNI语法和函数编写规则。下面首先介绍java基本类型和引用类型跟JNI本地相关类型的对照,然后完成一个简单的demo。

1. 对照表

Java类型 本地类型 描述
boolean jboolean C/C++8位整型
byte jbyte C/C++带符号的8位整型
char jchar C/C++无符号的16位整型
short jshort C/C++带符号的16位整型
int jint C/C++带符号的32位整型
long jlong C/C++带符号的64位整型e
float jfloat C/C++32位浮点型
double jdouble C/C++64位浮点型
Object jobject 任何Java对象,或者没有对应java类型的对象
Class jclass Class对象
String jstring 字符串对象
Object[] jobjectArray 任何对象的数组
boolean[] jbooleanArray 布尔型数组
byte[] jbyteArray 比特型数组
char[] jcharArray 字符型数组
short[] jshortArray 短整型数组
int[] jintArray 整型数组
long[] jlongArray 长整型数组
float[] jfloatArray 浮点型数组
double[] jdoubleArray 双浮点型数组

2.打开eclipse,创建一个Android应用,名称:AndroidNDKTest

(1)打开自动生成的MainActivity.java,添加内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MainActivity extends Activity {
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super .onCreate(savedInstanceState);
 
         TextView  tv = new TextView( this );
         tv.setText( stringFromJNI() );
         setContentView(tv);
         printString( "hello" );
     }
 
     /**
      * 从c/c++文件中返回字符串
      * @return
      */
     public native String  stringFromJNI();
 
     /**
      * 在c/c++文件中打印log信息
      * @param info
      */
     public native void printString(String info);
 
     static {
         System.loadLibrary( "hello-jni" );
     }
}

上面代码中,我们声明了两个本地函数,在返回值前添加了native标志,表明是在c/c++定义实现的。
(2)在项目根目录下创建一个jni文件夹,创建一个hello-jni.c文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <string.h>
#include <jni.h>
#include <android/log.h>
 
JNIEXPORT jstring JNICALL
Java_com_example_ndktest_MainActivity_stringFromJNI( JNIEnv* env,
                                                   jobject thiz )
{
     return (*env)->NewStringUTF(env, "Hello from JNI !" );
}
 
JNIEXPORT void JNICALL
Java_com_example_ndktest_MainActivity_printString( JNIEnv* env,jobject thiz,jstring info)
{
     const jchar* strDest;
     strDest = (*env)->GetStringUTFChars(env,info,NULL);
     if (strDest == NULL)
     {
         return NULL;
     }
     __android_log_print(ANDROID_LOG_INFO, "printString" , strDest);
     (*env)->ReleaseStringUTFChars(env,info,strDest);
}

JNIEXPORT和JNICALL都是JNI的关键字,是一些宏,这里不写也可以(JNIEXPORT jstring JNICALL可以改成jstring)。java的String对象对应于jni的jstring类型,但是在本地方法中不能直接使用,需要先转换成char*,这里使用GetStringUTFChars方法将传进来的jstring类型转换成为UTF-8格式的char*,就能够在本地方法中使用了。注意:使用完你所转换之后的对象之后,需要显示调用ReleaseStringUTFChars方法,让JVM释放转换的对象的空间,如果不显示的调用的话,该对象不会被垃圾回收器回收,因此可能会导致内存溢出。
下面是访问String的一些方法:
GetStringUTFChars 将jstring转换成为UTF-8格式的char*
GetStringChars 将jstring转换成为Unicode格式的char*
ReleaseStringUTFChars 释放指向UTF-8格式的char*的指针
ReleaseStringChars 释放指向Unicode格式的char*的指针
NewStringUTF 创建一个UTF-8格式的String对象
NewString 创建一个Unicode格式的String对象
GetStringUTFLength 获取UTF-8格式的char*的长度
GetStringLength 获取Unicode格式的char*的长度

(3) 添加一个Android.mk,相当于makefile,用来实现自动化编译的。内如如下:

1
2
3
4
5
6
7
8
9
LOCAL_PATH := $(call my- dir )
 
include $(CLEAR_VARS)
 
LOCAL_LDLIBS := -llog
LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
 
include $(BUILD_SHARED_LIBRARY)

这里添加了LOCAL_LDLIBS := -llog和hello-jni.c中添加了#include <android/log.h>头文件,是为了实现在c/c++代码中打印log信息的,以便在logcat中查看。
(4)配置ndk编译环境,这个在我的这篇文章里有详细说明。
(5)clean,然后运行程序,如果不出错,结果如下图:
模拟器


LogCat打印信息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值