今天终于将第一个 Android NDK 程序编译、运行成功

今天终于将第一个 NDK 程序编译、运行成功。
起先看资料和书籍时,都要求安装 CygWin。我也安装了,并将 Sample: hello-jni 编译成功。编译的 LOG 如下: 
LeoZheng@LeoZheng-PC /cygdrive/d/Android-Linux/android-ndk-r10c/samples/hello-jni
$ ../../ndk-build
[arm64-v8a] Gdbserver      : [aarch64-linux-android-4.9] libs/arm64-v8a/gdbserver
[arm64-v8a] Gdbsetup       : libs/arm64-v8a/gdb.setup
[x86_64] Gdbserver      : [x86_64-4.9] libs/x86_64/gdbserver
[x86_64] Gdbsetup       : libs/x86_64/gdb.setup
[mips64] Gdbserver      : [mips64el-linux-android-4.9] libs/mips64/gdbserver
[mips64] Gdbsetup       : libs/mips64/gdb.setup
[armeabi-v7a] Gdbserver      : [arm-linux-androideabi-4.6] libs/armeabi-v7a/gdbserver
[armeabi-v7a] Gdbsetup       : libs/armeabi-v7a/gdb.setup
[armeabi] Gdbserver      : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
[armeabi] Gdbsetup       : libs/armeabi/gdb.setup
[x86] Gdbserver      : [x86-4.6] libs/x86/gdbserver
[x86] Gdbsetup       : libs/x86/gdb.setup
[mips] Gdbserver      : [mipsel-linux-android-4.6] libs/mips/gdbserver
[mips] Gdbsetup       : libs/mips/gdb.setup
[arm64-v8a x86_64 mips64 armeabi-v7a armeabi x86 mips] Cygwin         : Generating dependency file converter script
[arm64-v8a] Compile        : hello-jni <= hello-jni.c
[arm64-v8a] SharedLibrary  : libhello-jni.so
[arm64-v8a] Install        : libhello-jni.so => libs/arm64-v8a/libhello-jni.so
[x86_64] Compile        : hello-jni <= hello-jni.c
[x86_64] SharedLibrary  : libhello-jni.so
[x86_64] Install        : libhello-jni.so => libs/x86_64/libhello-jni.so
[mips64] Compile        : hello-jni <= hello-jni.c
[mips64] SharedLibrary  : libhello-jni.so
[mips64] Install        : libhello-jni.so => libs/mips64/libhello-jni.so
[armeabi-v7a] Compile thumb  : hello-jni <= hello-jni.c
[armeabi-v7a] SharedLibrary  : libhello-jni.so
[armeabi-v7a] Install        : libhello-jni.so => libs/armeabi-v7a/libhello-jni.so
[armeabi] Compile thumb  : hello-jni <= hello-jni.c
[armeabi] SharedLibrary  : libhello-jni.so
[armeabi] Install        : libhello-jni.so => libs/armeabi/libhello-jni.so
[x86] Compile        : hello-jni <= hello-jni.c
[x86] SharedLibrary  : libhello-jni.so
[x86] Install        : libhello-jni.so => libs/x86/libhello-jni.so
[mips] Compile        : hello-jni <= hello-jni.c
[mips] SharedLibrary  : libhello-jni.so
[mips] Install        : libhello-jni.so => libs/mips/libhello-jni.so

到实际编写自己的 NDK 程序时,才发现了如下一段话:
谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK。
而在NDKr7开始,Google的Windows版的NDK提供了一个ndk-build.cmd的脚本,这样,就可以直接利用这个脚本编译,而不需要使用Cygwin了。只需要为Eclipse Android工程添加一个Builders,而为Eclipse配置的builder,其实就是在执行Cygwin,然后传递ndk-build作为参数,这样就能让Eclipse自动编译NDK了。
具体的Eclipse配置 builder 的方法,就不说了,网上有现成的。如: http://www.cnblogs.com/yejiurui/p/3476565.html

D:\Android-Linux\workspace\NDKEumClick>
D:\Android-Linux\workspace\NDKEumClick\bin\classes>javah com.hs.leozheng.ndkeumclick.jniClick
生成的 .h 文件位于目录: workspace\NDKEumClick\bin\classes
com_hs_leozheng_ndkeumclick_jniClick.h

新建文件 com_hs_leozheng_ndkeumclick_jniClick.c,并输入代码。
Android.mk 的内容如下: 
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jniClick
LOCAL_SRC_FILES := com_hs_leozheng_ndkeumclick_jniClick.c
include $(BUILD_SHARED_LIBRARY)

完成后在 Android 中可以看到如下 Log:
Android NDK: WARNING: APP_PLATFORM android-21 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml
Android NDK: WARNING: Unsupported source file extensions in jni/Android.mk for module jniClick
Android NDK:   com_hs_leozheng_ndkeumclick_jniClick.h
[armeabi] Install        : libjniClick.so => libs/armeabi/libjniClick.so
 
调用 .so 的 Android 工程代码如下:
public class MainActivity extends ActionBarActivity {
static {
        System.loadLibrary("jniClick");
    }

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

String str = jniClick.AddStr("test", "test");
Log.i("NDK", "jni addStr function: "  + str);

int ret = jniClick.AddInt(10, 6);
Log.i("NDK", "jni addInt function: " + Integer.toString(ret));


......
}
 
 FATAL EXCEPTION: main
 java.lang.UnsatisfiedLinkError: AddStr
  at com.hs.leozheng.ndkeumclick.jniClick.AddStr(Native Method)
  at com.hs.leozheng.ndkeumclick.MainActivity.onCreate(MainActivity.java:19)
  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:123)
  at android.app.ActivityThread.main(ActivityThread.java:3683)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:507)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
  at dalvik.system.NativeStart.main(Native Method)

错误产生的原因:
在 Android.mk 错误的将 LOCAL_SRC_FILES 设置为头文件: com_hs_leozheng_ndkeumclick_jniClick.h
正确的应该是: 
LOCAL_SRC_FILES := com_hs_leozheng_ndkeumclick_jniClick.c

posted @ 2016-02-16 17:03  91program  阅读(902)  评论(0编辑  收藏  举报