2011年07月25日

目前正在学习JNI,从一开始的一无所知,到现在的略知一二,走了不少弯路,为了让有兴趣的同行少走弯路,下面把我的经验记录下来,给大家一个参考:

1、先从SimpleJNI说起:

在Android SDK的源码目录下./development/samples/SimpleJNI可以找到一个最简单的JNI例子,其文件树如下

.
|-- AndroidManifest.xml
|-- Android.mk
|-- jni
| |-- Android.mk
| `-- native.cpp
`-- src
`-- com
`-- example
`-- android
`-- simplejni
`-- SimpleJNI.java

该例子的主要思想是用JNI生成一个本地库libsimplejni.so,实现一个add(a,b)功能,然后通过SimpleJNI.java调用该库输出显示信息

此例子的Android.mk文件如下:


1 # This makefile shows how to build a shared library and an activity that
2 # bundles the shared library and calls it using JNI.
3
4 TOP_LOCAL_PATH:= $(call my-dir)
5
6 # Build activity
7
8 LOCAL_PATH:= $(TOP_LOCAL_PATH)
9 include $(CLEAR_VARS)
10
11 LOCAL_MODULE_TAGS := samples
12
13 LOCAL_SRC_FILES := $(call all-subdir-java-files) #查找当前目录下所有的java文件
14
15 LOCAL_PACKAGE_NAME := SimpleJNI                    #编译一个java包:SimpleJNI.apk
16
17 LOCAL_JNI_SHARED_LIBRARIES := libsimplejni #编译一个动态库:libsimplejni.so
18
19 LOCAL_PROGUARD_ENABLED := disabled
20
21 include $(BUILD_PACKAGE)
22
23 # ============================================================
24
25 # Also build all of the sub-targets under this one: the shared library.
26 include $(call all-makefiles-under,$(LOCAL_PATH))

在Android SDK的根目录下面运行终端,输入如下编译命令:

make SimpleJNI libsimplejni

将得到如下两个文件:


out/target/product/sdkDemo/system/app/SimpleJNI.apk
out/target/product/sdkDemo/system/lib/libsimplejni.so
JNI代码的目录为jni/vative.cpp,其内容如下:






View Code

编译此JNI代码所需要的Android.mk如下:


1 # This makefile supplies the rules for building a library of JNI codefor
2 #use by our example of how to bundleashared library with an APK.
3
4 LOCAL_PATH:= $(call my-dir)
5 include $(CLEAR_VARS)
6
7 LOCAL_MODULE_TAGS := samples
8
9 # This is the target being built.
10 LOCAL_MODULE:= libsimplejni
11
12
13 # All of the source files that we will compile.
14 LOCAL_SRC_FILES:= \
15    native.cpp
16
17 # All of the shared libraries we link against.
18 LOCAL_SHARED_LIBRARIES := \
19    libutils
20
21 # No static libraries.
22 LOCAL_STATIC_LIBRARIES :=
23
24 # Also need the JNI headers.
25 LOCAL_C_INCLUDES += \
26    $(JNI_H_INCLUDE)
27
28 # No special compiler flags.
29 LOCAL_CFLAGS +=
30
31 # Don't prelink this library.    For more efficient code, you may want
32 # to add this library to the prelink map and set this to true. However,
33 # it's difficult to do this for applications that are not supplied as
34 # part of a system image.
35
36 LOCAL_PRELINK_MODULE := false        #不需要重新链接此库
37
38 include $(BUILD_SHARED_LIBRARY)


应用部分的代码目录为/src/com/example/android/simplejni/SimpleJNI.java,在这个类中Native类是对本地方法的封装,内容如下:








1 class Native {                                                                //定义Java的封装类
      static {
      // The runtime will add "lib" on the front and ".o" on the end of
      // the name supplied to loadLibrary.
          System.loadLibrary("simplejni");                //加载本地库
      }
7
      static native int add(int a, int b);                    //调用本地方法
9 }

在这个类中调用的过程如下:

1 public class SimpleJNI extends Activity {
     
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          TextView tv = new TextView(this);                                                //建立一个UI中的类TextView
          int sum = Native.add(2, 3);                                                                //通过封装类调用本地方法
          tv.setText("2 + 3 = " + Integer.toString(sum));                        //设置显示内容
          setContentView(tv);
10        }
11 }

通常JNI的使用自下而上有4个层次:本地库、JNI库、声明本地接口的Java类,Java调用者。在本例中,本地库和JNI库合二为一,声明本地接口的Java类和Java调用者合二为一。

2、将以上所得到的libsimplejni.so与SimpleJNI.apk两个文件从Ubuntu中拷贝出来,放置在windows C盘的根目录下,

运行Android模拟器

在windows的“运行”中输入cmd打开windows的命令窗口

输入cd c:\命令切换到C盘根目录下

然后输入adb version确实系统是否已经安装了adb工具,如果已经安装将得到如下内容

Android Debug Bridge version 1.0.26

如果没有安装,可以到\android-sdk-windows\tools目录下将adb.exe和AdbWinApi.dll两个文件拷贝到windows C盘的system32目录下即可

然后输入如下命令将libsamplejni.so拷贝到模拟器的system/lib目录下


adb push libsamplejni.so /system/lib

再输入如下命令把SampleJNI.apk拷贝到模拟器的system/app目录下


adb push SampleJNI.apk

上面可能遇到的问题解决办法:

(1)、提示failed to copy 'libsimplejni.so'to'/system/lib/libsimplejni.so':Read-only file system

这是因为当前状态下,此目录是一个只读目录,输入如下命令就可以获得写的权限


adb remount

(2)、提示failed to copy 'libsimplejni.so'to'/system/lib/libsimplejni.so':Out of memory

这是因为建议模拟器的时候默认的系统memory太小了,关闭当前模拟器,输入如下命令就可以解决此问题


emulator -avd Android2.2 -partition-size 128

说明:其中Android2.2是我当前所建AVD的名称,128代表的是设置的系统memory的大小,输入此命令之后将会自动打开模拟器

一切正常后,输入相应命令后将得到:



C:\>adb push libsimplejni.so /system/lib
40 KB/s (5188 bytes in 0.125s)

C:\>adb push SimpleJNI.apk /system/app
52 KB/s (5064 bytes in 0.093s)

在模拟器中,我们将看到已经安装好了的Simple JNI运行它之后

将得到我们所期望的结果

2+3=5

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值