(Android) NDK

来源:互联网 发布:数据魔方的作用 编辑:程序博客网 时间:2024/05/02 00:30

從 Android NDK | Android Developers 下载 Android NDK (我在 Ubuntu 所以下载 android-ndk-r5c-linux-x86.tar.bz2) 並挑选一个地方解压缩(此例为 ~/android-ndk-r5c),除此之外要把 Android SDK 更新至最新版,如果已经安裝好 Android 开发环境,更新方式透过 Eclipse -> [Window]-> [Android SDK and AVD Manager] -> [Installed packages] -> [Update All...]

接着要进行 NDK 环境设置,可查看 android-ndk-r5c/docs/INSTALL.html,可以得知 Android NDK 至少需使用 Android 1.5 系統,而编译环境至少是 GNU Make 3.8.1,除此之外还需要 Nawk 或 GNU Awk 工具,而常見的 awk 则不适用。

在 Ubuntu 10.04 64-bit desktop 环境上:

$ awk -W version
GNU Awk 3.1.6
Copyright (C) 1989, 1991-2007 Free Software Foundation.
~$ make -version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc

透过Eclipse 建立一个 android 2.3.3 project,例如 MyNDK:

Project name: MyNDK
Build Target: Android 2.3.3/Android Open Source Project/2.3.3/10
Application name: MyNDK
Package name: com.example.ndk
Create Activity: MyNDK
Min SDK Version: 3

接著,在 Eclipse 左边 Project Explorer 建立 jni 和 libs 两个目录,位置摆在刚刚的 Project 里(点一下 MyNDK,接着按右键选 New -> Folder 输入 jni,之后在建立 libs 目录):

MyNDK/jni
MyNDK/libs

在 MyNDK/jni 里头新增两个档案,分別是 JNI 程式码和 Android.mk,结构如下:

MyNDK/jni
MyNDK/jni/Android.mk
MyNDK/jni/my-jni.c

其中 Android.mk 和 .c 可以从 android-ndk-r5c/samples/hello-jni/jni 里头寻得范例:

MyNDK/jni/Android.mk (參考 android-ndk-r5c/samples/hello-jni/jni/Android.mk)

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := my-jni
LOCAL_SRC_FILES := my-jni.c
include $(BUILD_SHARED_LIBRARY)

MyNDK/jni/my-jni.c (參考 android-ndk-r5c/samples/hello-jni/jni/hello-jni.c)

#include <string.h>
#include <jni.h>
jstring Java_com_example_ndk_MyNDK_stringFromJNI( JNIEnv* env, jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from My JNI !");
}

其中要留意 function name,里头包括 packages name 和 Activity name 等信息,此例是 com_example_ndk 和 MyNDK。

接著要透过 android ndk 去编译 my-jni.c,除了在 Command line 可以切换到 MyNDK 目录,用 android-ndk-r5c/ndk-build 进行编译外,還可以透过 Eclipse 设定好,让你每次自动编译好:

Properties for MyNDK

在 Eclipse 左边 Project Explorer 点选 MyNDK,选右键 -> Properties -> Builders -> New -> Program

在 Main 分页:

Name: NDK_Builder
Location(ndb-build位置): /home/user/android-ndk-r5c/ndk-build
Working Directory:(project位置): ${workspace_loc:${project_path}}

Builders

在 Refresh 分页:

將 Refresh resources upon completion 打勾,並且在 Specific resources 选择 MyNDK/libs 目录

在 Build Options 分页:

勾选 Allocate Console(necessary for input)、Launch in backgroud、After a "Clean"、During manual builds、During auto builds 和 Specify working set of relevant resources

在 Specific resources 选择 MyNDK/jni

如此一來,只要编译或清除時,自动会编译jni 的部份,可以使用 Build all(快捷键Ctrl+B) 试试,可以看到 Console 的输出:

Compile thumb  : my-jni <= my-jni.c
SharedLibrary  : libmy-jni.so
Install        : libmy-jni.so => libs/armeabi/libmy-jni.so

接着,才正式要写 Java 程式部份,切换到 MyNDK.java:

package com.example.ndk;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MyNDK extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.main);
        TextView  tv = new TextView(this);
        tv.setText( stringFromJNI() );
        setContentView(tv);

    }
    public native String  stringFromJNI();
    static {
        System.loadLibrary("my-jni");
    }

}

其中特別的是要宣告 jni 使用到的函数,这跟 my-jni.c 的宣告有关,以及 System.loadLibrary 的部份,跟 jni/Android.mk 设定的编译结果也有关系,如果都不相符,执行时会出現 exception。

最后跑起来的效果:

MyJNI

整个Project结构:

Project Explorer




One Error on NDK-r8d

failed. d:/Development/android/android-ndk-r8d/build/gmsl/__gmsl:512: *** non-numeric second argument to `wordlist' function: ''. Stop.

Solution:

int_encode = $(__gmsl_tr1)$(wordlist 1, $1,$(__gmsl_input_int))
=>
int_encode = $(__gmsl_tr1)$(wordlist 1,$(words $1),$
(__gmsl_input_int))




原创粉丝点击