Android NDK基礎編程入門

來源:互聯網
上載者:User

對於還不瞭解Android NDK作用和搭建的朋友,可以先參考下Android NDK作用與搭建,今天這篇文章是建立在已經搭建好Android NDK開發環境,來看看NDK編程 "Hello Jni"的實現。

首先Android NDK開發需要具備哪些基礎知識?

1.熟悉Android應用開發

2.熟悉C語言(編寫底層.so庫需要用到)

3.瞭解Linux(要知道一些常用的命令)

下面開啟NDK包下Sample目錄下的“hello-jni”例子工程

如可以看到,就是一個普通Android應用程式,在Src目錄裡有個HelloJni.Java程式,不同的是多了一個“jni”目錄,JNI(Java Native Interface,中文為JAVA本地調用),JNI的作用:可以通過Java程式訪問到其他語言(主要是C/C++)寫出來的庫(linux平台.so庫,Windows平台.dll庫),其中NDK會通過“.mk“檔案將“hello-jni.c”C語言檔案編譯成需要的.so庫,預設情況下“.mk“檔案不需要修改,有興趣的朋友可以百度下JNI更多相關資料。

下面將此例子代碼匯入到eclipse中,剛開始研究時只用匯入第一個HelloJni項目就行了

先看看HelloJni.Java

/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.hellojni;import android.app.Activity;import android.widget.TextView;import android.os.Bundle;public class HelloJni extends Activity{    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        /* Create a TextView and set its content.         * the text is retrieved by calling a native         * function.         */        TextView  tv = new TextView(this);        tv.setText( stringFromJNI() );        setContentView(tv);    }    /* A native method that is implemented by the     * 'hello-jni' native library, which is packaged     * with this application.     */    public native String  stringFromJNI();    /* This is another native method declaration that is *not*     * implemented by 'hello-jni'. This is simply to show that     * you can declare as many native methods in your Java code     * as you want, their implementation is searched in the     * currently loaded native libraries only the first time     * you call them.     *     * Trying to call this function will result in a     * java.lang.UnsatisfiedLinkError exception !     */    public native String  unimplementedStringFromJNI();    /* this is used to load the 'hello-jni' library on application     * startup. The library has already been unpacked into     * /data/data/com.example.hellojni/lib/libhello-jni.so at     * installation time by the package manager.     */    static {        System.loadLibrary("hello-jni");    }}

我們Crowdsourced Security Testing道這行代碼System.loadLibrary("hello-jni");就可以訪問到“hello-jni.c”檔案編譯後的.so庫,然後tv.setText( stringFromJNI() );就可以調用到“hello-jni.c”C檔案中的函數。

這行代碼public native String stringFromJNI();表示介面的申明,返回字串。直接映射到了C檔案中的調用函數。

接著看下hello-jni.c

/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */#include #include /* This is a trivial JNI example where we use a native method * to return a new VM String. See the corresponding Java source * file located at: * *   apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java */jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,                                                  jobject thiz ){#if defined(__arm__)  #if defined(__ARM_ARCH_7A__)    #if defined(__ARM_NEON__)      #define ABI "armeabi-v7a/NEON"    #else      #define ABI "armeabi-v7a"    #endif  #else   #define ABI "armeabi"  #endif#elif defined(__i386__)   #define ABI "x86"#elif defined(__mips__)   #define ABI "mips"#else   #define ABI "unknown"#endif    return (*env)->NewStringUTF(env, "huahua Hello from JNI !  Compiled with ABI " ABI ".");}

對Java_com_example_hellojni_HelloJni_stringFromJNI函數返回的字串做了一點小小的修改,其中函數第一個參數 JNIEnv是Google所提供的用於Java和C互動的一種結構,結構的細節暫時不去深究,Crowdsourced Security Testing道通過return返回這行代碼的文法就可以把某項內容返回給來自於Java檔案的調用者stringFromJNI()。

這裡可能會有疑問stringFromJNI()和Java_com_example_hellojni_HelloJni_stringFromJNI()兩個方法的名字不一樣,其實C檔案中最後一個"_"後面的名字就是Java中調用的介面的名字,前面則是包名的結構,這種寫法的原因是來自gcc編譯器的,而且是有關聯規則。

下面直接在手機上運行下工程,出現彈錯!,logcat資訊如下

因為現在.so庫還不存在呢,需要我們自己通過mk檔案,C檔案編譯出來。開啟控制台,進入到E:\android-ndk-r9d\samples\hello-jni\jni目錄,輸入ndk-build

ndk-build這個指令碼程式會完成編譯,產生.so庫等等一切的相關工作,執行完後在工程下多了"libs"和"obj"2個子目錄,

在libs中會根據不同CPU硬體產生各自的.so庫,這個暫時不用去深究。

這時重新整理一下eclipse中的工程,libs中的.so庫就加入進去了,運行程式效果如下

說明上層Java程式調用底層.so庫中的函數OK,這樣一個簡單的JNI調用就完成了。

我們再看下在HelloJni.Java中

static {
System.loadLibrary("hello-jni");
}

這個文法表示在類載入時,就會調用System.loadLibrary("hello-jni");,去載入hello-jni這個庫。這個名字在代碼中是這樣寫,在實際中linux平台中左邊會多上lib3個字母,右邊會多上.so。其實就是我們編譯出來的libs目錄中的libhello-jni.so庫。如果在Windows平台下右邊會是.dll。庫個名稱和程式中寫的是相互對應的,這是由作業系統規定必須這樣寫的。

好了,Android NDK的基礎編程入門就說到這裡。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.