Eclipse下Android的NDK開發環境配置


  編輯2016年7月26日——增加了下載網址,修改了一些錯誤。

 

  摸索了一周,走了很多彎路,磕磕絆絆,總算是弄好了NDK的開發環境,在這里總結一下吧。

一、Android NDK開發環境

   首先下載安裝JRE、JDK,不必多說。然后下載NDK包,建議下載r11版本后的,自帶C/C++的編譯器, 不需要使用外部編譯器的麻煩了,而且同時支持32位和64位的ARM處理器。下載完NDK包后,解壓縮即可,需要之后關聯到Eclipse。然后下載ADT Bundle,即安卓開發工具套裝,里面集成好的Eclipse的安卓開發環境,但是,里面的版本可能較低而且沒有集成NDK功能,下載新版的ADT包,進行更新。

  開發環境推薦下載網站:http://tools.android-studio.org/index.php

  關於SDK更新,由於長城防火牆的原因,導致無法更新SDK。可以進行如下設置,進行SDK更新。

  HTTP Proxy Server 設置為  mirrors.neusoft.edu.cn

  HTTP Proxy Port 設置為    80

  其他設置如下圖

  設置好了之后進行Reload,然后選擇需要的工具包進行安裝。

  之后是ADT更新,下載最新的ADT包,然后在Eclipse的Help->Install New Software中進行離線更新,點擊add彈出窗口,Name可以任意填寫,location處單擊Aarchive選擇本地已經下載的adt插件。

  完成更新后,在Preferences中的Android這一欄里出現了NDK,選擇后設置NDK的路徑即可,路徑設置到包含ndk-build.cmd文件的目錄下,一般是ndk的根目錄,或者根目錄的build文件夾下。

  以上所有開發工具配置完成后,就可以進行期待的NDK開發了~~

 

二、運行NDK官方例子hello-jni

  首先導入hello-jni到工作空間中,File->Import,選擇Existing Android Code Into Workspace,點擊next,然后在Root Directory中瀏覽找到NDK文件夾下的samples下的hello-jni選中,然后如下圖勾選,完成工程導入,整個工程就被復制到工作空間中了。

  導入后,可以在工程瀏覽窗口中看到工程結構,如下圖

  右鍵這個工程,Android Tools->Add Native Support,進入后直接點完成即可。

  這樣,我們就可以編譯運行了。

 

三、編寫自己的第一個一個NDK的應用

  我們將編寫一個NDK應用,其功能是調用本地方法getNum(),獲取一個整數,然后顯示出來。

  首先新建工程,取名為MyFirstJni,我這里選擇的最低API 16,其他的是API 19,其余默認設置,建立工程。

  之后在工程的MainActivity中,編寫代碼如下:

package com.pplxlee.myfirstjni;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends Activity {

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

        TextView tv = new TextView(this);
        tv.setText(String.valueOf(getNum()));    // 通過getNum方法得到int型數字,轉換為Sting給tv
        setContentView(tv);        // 顯示tv的內容
    }
    
    private native int getNum();    // 聲明Native方法getNum
    
    static {
        System.loadLibrary("MyFirstJni");    // 載入動態鏈接庫libMyFirstJni.so
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

 

  然后右鍵工程,Android Tools->Add Native Support,進入后注意框里面的名字要和MainActivity的程序中加載的動態鏈接庫的名字相同,這里輸入"MyFirstJni"直接點完成即可。

  我們會看到產生了新的文件夾jni,並生成了文件MyFirstJni.cpp和Android.mk。MyFirstJni.cpp用於編寫C++代碼,去定義getNum()方法的具體實現過程,而Android.mk則描述了編譯C++成庫的方式。

  對比官方jni的例子,我們可以發現,我們還少了一個Application.mk,我們可以在我們工程里也加入這樣的一個文件,文件內容為APP_ABI := all,這個文件使得編譯器生成其支持的全平台的so文件,如果針對某一平台開發,可以具體設置。

  由於編寫jni的C++代碼有自己的規范,為了方便,可以通過jdk的javah工具,來自動生成頭文件,方法如下。

  打開外部工具配置,新建工具javah4android,做如下設置(注意:Android JNI的生成配置和Java JNI的生成配置不同,無法混用):

Location:

  瀏覽jdk\bin目錄,找到javah.exe

WorKing Directory:

  ${project_loc}

Arguments:      

  -v -classpath "${project_loc}/src"
  -d "${project_loc}/jni"
  -jni ${java_type_name}

設置完后選擇應用。然后,在光標在MainActivity.java內的情況下,運行此工具。會看到在jni文件夾內生成了com_pplxlee_myfirstjni_MainActivity.h的文件。

  打開后可以看到代碼如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_pplxlee_myfirstjni_MainActivity */

#ifndef _Included_com_pplxlee_myfirstjni_MainActivity
#define _Included_com_pplxlee_myfirstjni_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_pplxlee_myfirstjni_MainActivity
 * Method:    getNum
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_pplxlee_myfirstjni_MainActivity_getNum
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

實際上就是聲明了JNIEXPORT jint JNICALL Java_com_pplxlee_myfirstjni_MainActivity_getNum(JNIEnv *, jobject)函數,對應與java代碼中的getNum函數,剩下的事情就是編碼實現getNum的功能了。不過這里可能會出現Eclipse的bug,就是點擊C++代碼時,可能會產生類型不能解析的錯誤,導致無法編譯運行。解決方法就是在編譯運行之前刪掉這些錯誤就好了。

  接下來編寫MyFirstJni.cpp文件如下:

#include "com_pplxlee_myfirstjni_MainActivity.h"

jint Java_com_pplxlee_myfirstjni_MainActivity_getNum
    (JNIEnv *,jobject) {
    return 100;
}

  然后編譯運行,在手機上的運行結果如下:

  自此,一個簡單的Android NDK程序完成了!

六、總結

  作為一個初學者,一定要靜下心來一點一點的學習,切忌心浮氣躁,會走很多彎路的!

  以后將學習如何在JNI中使用stl庫和Opencv庫等,學好后將會繼續分享到我的博客上面。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM