安卓开发什么时候使用jni

http://zhidao.baidu.com/link?url=0BGq9nfwWoXaXi9-mL-btbxfTG1-OHyt7iR0Jqlg99aillKUrzHCNtEVmkgZJ5FNee1m3L2ngNSEFF2mALSO4PnRfAp7ccexR_G5Fe2Fv87



android JNI是连接android Java部分和C/C++部分的纽带,完整使用JNI需要Java代码和C/C++代码。其中C/C++代码用于生成库文件,Java代码用于引用C /C++库文件以及调用C/C++方法。

android Java部分代码:

jnitest.java     
02          
03     package  com.hello.jnitest;     
04          
05           
06          
07     import  android.app.Activity;     
08          
09     import  android.os.Bundle;     
10          
11           
12          
13     public  class  jnitest  extends  Activity {     
14          
15         /** Called when the activity is first created. */    
16          
17         @Override    
18          
19         public  void  onCreate(Bundle savedInstanceState) {     
20          
21             super .onCreate(savedInstanceState);     
22          
23             setContentView(R.layout.main);     
24          
25             Nadd test =  new  Nadd();     
26          
27             setTitle( "The Native Add Result is " +String.valueOf(test.nadd( 10 20 )));     
28          
29         }      
30          
31     }     
32          
33     Nadd.java     
34          
35     package  com.hello.jnitest;     
36          
37           
38          
39     public  class  Nadd {     
40          
41     static  {     
42          
43     System.loadLibrary( "hello_jni" );     
44          
45     }     
46          
47           
48          
49     public  native  int  nadd( int  a,  int  b);     
50          
51     }

Java代码说明:

1)jnitest.java是一个activity的类对象,在该类对象中生成调用JNI函数的类对象,同时调用JNI方法,最后将JNI方法的结果显示到标题栏上;

2)Nadd.java是一个引用和声明JNI库和函数的类,其中System.loadLibrary();函数用来引用JNI库,默认JNI库放在 android系统的/system/lib/目录下;public nadd int nadd(int a, int b);为声明需要在java程序中使用的JNI库中的函数;

JNI中java部分的代码到此就结束了,总结一下在java代码中需要做两件事:

1)使用System.loadLibrary()函数来引用JNI库;

2)声明调用JNI库的函数且前面添加native关键字;


android C/C++部分代码:

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
30
31
32
33
34
35
36
01    #define LOG_TAG  "hello-JNI"     
02    #include <stdio.h>     
03    #include <stdlib.h>     
04    #include <unistd.h>     
05    #include <sys/types.h>     
06    #include <sys/stat.h>     
07    #include <fcntl.h>     
08    #include < assert .h>     
09    #include  "jni.h"     
10    #include  "JNIHelp.h"     
11    #include  "android_runtime/AndroidRuntime.h"     
12     static  jint com_hello_jnitest_jnitest_nadd(JNIEnv *env, jobject obj, jint a, jint b)     
13    {     
14     return  (a * b);     
15    }     
16     static  JNINativeMethod gMethods[] = {     
17    { "nadd" "(II)I" , ( void  *)com_hello_jnitest_jnitest_nadd},     
18    };     
19     static  int  register_android_test_hello(JNIEnv *env)     
20    {     
21     return  android::AndroidRuntime::registerNativeMethods(env,  "com/hello/jnitest/Nadd" , gMethods, NELEM(gMethods));     
22    }     
23    jint JNI_OnLoad(JavaVM *vm,  void  *reserved)     
24    {     
25    JNIEnv *env = NULL;     
26     if  (vm->GetEnv(( void  **)&env, JNI_VERSION_1_4) != JNI_OK) {     
27     printf ( "Error GetEnv\n" );     
28     return  -1;     
29    }     
30     assert (env != NULL);     
31     if  (register_android_test_hello(env) < 0) {     
32     printf ( "register_android_test_hello error.\n" );     
33     return  -1;     
34    }     
35     return  JNI_VERSION_1_4;     
36    }

JNI C/C++代码说明:

1)JNI_OnLoad()函数。该函数在Java程序调用System.loadLibrary()时,被调用执行,用于向JavaVM注册JNI函数等。在本例中首先通过参数JavaVM(Java虚拟机指针)获取当前应用程序所在的线程,即:JNIEnv。再通过调用 android::AndroidRuntime::registerNativeMethods()注册native实现的函数指针。

2)JNI函数和Java调用函数的映射关系。使用JNINativeMethod将java调用的函数名与JNI实现的函数名联系在一起;

3)JNI函数实现;


Android.mk代码:

1
2
3
4
5
6
7
8
9
1     LOCAL_PATH := $(call my-dir)     
2     include $(CLEAR_VARS)     
3     LOCAL_PRELINK_MODULE :=  false    
4     LOCAL_SRC_FILES := \     
5     com_hello_jnitest.cpp     
6     LOCAL_SHARED_LIBRARIES := \     
7     libandroid_runtime     
8     LOCAL_MODULE := libhello_jni     
9     include $(BUILD_SHARED_LIBRARY)

需要注意的是:

1)JNI C/C++部分的代码需要在android源代码树上进行编译,编译完成后我的做法是直接将生成的.so通过adb push方法上传到android虚拟机的/system/lib/目录下;

2)java代码可以在eclipse下直接编译且在虚拟机上执行;


编译JNI C/C++部分代码(在android内核源代码根目录下):

#make libhello_jni

之后在out/target/product/generic/system/lib/目录下生成libhello_jni.so


上传libhello_jni.so到android虚拟机:

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

注意:此时有可能出现Out of Memory的错误提示。当出现如上错误提示时,需要使用#adb remount重新加载一下就可以了。

另外,也有可能直接使用eclipse启动android虚拟机时出现上述错误且使用#adb remount也出现的情况,此时需要手动启动android虚拟机,如:#emulator -avd xxx -partition-size 128,之后在使用#adb push就可以了。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值