Android開發--NDK之環境搭建

android 中爲何實用NDK,網上一搜一大堆,在這緣由不在贅述。java

在Android SDK首次發佈時,Google就宣稱其虛擬機Dalvik是支持JNI編程方式的;也就是第三方的應用是能夠調用本身公司的或者是其餘C、C++動態庫。linux

搭建平臺:1.我這用的是MacBook,系統是OS X 10.11.5;android

                  2.Android Studio 2.1.2
c++

                  3.JDK1.8.0_77 x86_64
編程

首先搭建NDK開發環境。啓動Android Studio,在Android studio中,屬性—>Appearance & Behaveor —> System Settings —> Android SDK選項(注意:windows在使用NDKr8版本之上的NDK編譯版本,是不須要cygwin來模擬linux,進行交叉編譯的)。以下圖所示:windows

wKiom1eDD0PRukVCAAdaML6qL6E045.png

打開右邊的SDK Tools下邊的選項欄有一個NDK的選項,打上對勾,點擊Apply按鈕,接着會出現下載NDK文件的對話框,點擊accept—>OK,會下載NDK文件,一般NDK會安裝到SDK的目錄下面。bash

下載安裝完成以後配置NDK環境變量:架構

1.Windows 上是在計算機—》屬性—》高級—》環境變量,在path上追加NDK的安裝目錄。app

2.linux或者是MAC是在家目錄的.bash_profile中,添加環境變量,例如export NDK_HOME=/Users/XXX/Android/SDK/ndk-bundle export PATH=$PATH:$SDK_HOMEide

OK.測試NDK是否安裝配置成功,打開終端,輸入ndk-build -version.回車

顯示

wKiom1eDED2T1ElgAAKFzKJlX4w955.png

表示安裝成功。

1.建立一個Android項目來測試一個Android的使用方式,在這命名爲JNIDemo;建立項目的過程再也不贅述。


2.在Andorid視圖中創建jni文件夾,右鍵—>New—>Folder—>JNI Folder,肯定。會建立一個jni目錄。這個目錄就是存放c源碼的文件。(jni目錄的建立,也能夠在project視圖中在main文件中建立一個jni目錄。若是在Android視圖中建立JNI Folder,再切換到Project視圖,你會發現,main目錄下有一個jni目錄,兩個本質上是一致的)。

3.配置須要CUP編譯成的架構庫(.so文件)。

defaultConfig {

    applicationId "com.zzh.jni"

    minSdkVersion 14

    targetSdkVersion 23

    versionCode 1

    versionName "1.0"

    ndk{

        moduleName "zzhJni」//c/c++編譯成的庫文件名稱

        abiFilters "armeabi", "armeabi-v7a","arm64-v8a","x86", "x86_64"//須要適配哪幾種類型的CPU架構。

    }

}

4.在gradle.properties(Project Properties)中添加android.useDeprecatedNdk=true;

    在local.properties中添加ndk.dir=/Users/XXX/Android/SDK/ndk-bundle(本身安裝NDK的路徑)

5.新建一個jni調用類NdkUtils寫一個native方法。在Java中,Java調用c/c++中的程序,須要使用到native關鍵字表示Java中調用C/C++中的方法。

package zzh;
public class NdkUtils {
    public static native String getMapHeader();
}

6.點擊Build—>Make Project,編譯文件,編譯後

wKioL1eDEUyQ4eCJAAEOMeVYKJM296.png

在終端,進入到debug目錄,運行javah -jni zzh.NdkUtils回車,生成c的頭文件,頭文件的命名爲「包名_類名(包名之間的「.」使用「_」分割開的)」。將此文件複製到jni目錄中,打開能夠看到一下內容

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

#ifndef _Included_zzh_NdkUtils
#define _Included_zzh_NdkUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     zzh_NdkUtils
 * Method:    getDeviceIdFromNdk
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_zzh_NdkUtils_getMapHeader
        (JNIEnv *env, jobject obj);
#ifdef __cplusplus
}
#endif
#endif

    · JNIEXPORT jstring JNICALL Java_zzh_NdkUtils_getMapHeader(JNIEnv *env, jobject obj); 就是咱們以前所用native在NdkUtils.java聲明的方法。這個只是C/C++的一個.h文件,方法的具體實現,還要一個.c。這個.c文件,本身建立就好。

方法實現以下

#include "zzh_NdkUtils.h"
JNIEXPORT jstring JNICALL Java_zzh_NdkUtils_getMapHeader
        (JNIEnv *env, jobject obj){
    return (*env) -> NewStringUTF(env, "string from c");
}

7.至此C語言,就寫好了,怎麼讓c/c++生成庫文件呢,先點擊Build-clean Project(先clean是由於避免在編譯的時候產生衝突),再make Project,在6步驟的圖片中classes同級目錄下有ndk目錄,此目錄下有生成好的庫文件。

wKiom1eDEouAOpHxAABjINxzj1I509.png

複製arm*、x86*到jniLibs目錄中,就像咱們在作項目時,將第三方的.so文件放入到jniLibs目錄同樣。Android.mk複製到jni文件中。

8.最後一步,調用生成的庫文件。

在NdkUtils.java中,添加

static{

System.loadLibrary(「zzhJni"); //這一行,表示要加載C語言庫,zzhJni就是編譯成的c庫文件,也就是在第三步中build.gradle中配置的moduleName 的名字

}

這樣就能夠在Java代碼中調用c/c++方法了。

示例:

在MainActivity.java中調用:

public class MainActivity extends Activity {
    private TextView mTextView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.textView);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    String str = "" + NdkUtils.getMapHeader();
                    mTextView.setText(str);
                } catch (Exception ex) {
                    ex.printStackTrace();
                } finally {

                }
            }
        });

    }
}

佈局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.zzh.jni.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="調用C方法"
        android:id="@+id/button"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:id="@+id/textView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"/>
</RelativeLayout>

運行截圖:

wKioL1eDF3CA-BtWAAGn7_z7YA0877.png

文筆有限,寫的很差,敬請原諒,若有錯誤,敬請指正

相關文章
相關標籤/搜索