【Android】NDK開發之開發環境搭建基礎篇

開頭

Android NDK官方介紹html

The Android NDK is a toolset that lets you implement parts of your app using native-code languages such as C and C++. For certain types of apps, this can help you reuse code libraries written in those languages.java

實如今你的Android應用中調用C程序實現一些功能。那爲何要在Java開發中使用C語言呢?android

  • 代碼的保護。因爲apk的java層代碼很容易被反編譯,而C/C++庫反匯難度較大。git

  • 能夠方便地使用現存的開源庫。大部分現存的開源庫都是用C/C++代碼編寫的。github

  • 提升程序的執行效率。將要求高性能的應用邏輯使用C開發,從而提升應用程序的執行效率。服務器

  • 便於移植。用C/C++寫得庫能夠方便在其餘的嵌入式平臺上再次使用。
    PS:資料來源app

雖然關於NDK開發的學習資料很少,Google官方並不少關於NDK開發文檔,但居然NDK開發包那必然有它的意義。因此咱們有必要對NDK開發有個初步認識。這節主要搭建NDK開發環境並在應用中調用native函數方法。函數

開發環境搭建

從ndk-7後,谷歌已經改良了ndk的操做,不需用使用cygwin來交叉編譯,因此這裏就再也不講cygwin的配置。所搭建的開發環境是Android Studio性能

  • 1.在官方下載Android NDK開發包 下載地址目前最新的版本爲r12b學習

  • 2.添加java系統環境變量(若是Android Studio的terminal中沒法使用javah指令的時候須要作此步操做)

變量
CLASSPATH .;%JAVA_HOME%lib;
JAVA_HOME X:XXJavajdk1.8.0_05
PATH %JAVA_HOME%bin;
  • 3.新建Android工程,添加項目構建NDK本地路徑
    圖片描述

  • 4.local.propertices中添加ndk.dir=c:\Android-ndk

  • 5.gradle.properties文件中添加android.useDeprecatedNdk=true

趁熱打鐵,寫demo實踐一下

  • 1.新建類JniFunction,實現兩個native方法

public class JniFunction {

    static public native String getJniString();//獲取字符串
    static public native int addNumber(int a,int b);//獲取兩個整數相加值
}
  • 2.rebuild Project,在工程目錄下app/intermediates/classes/debug下查找到JniFunction.class

  • 3.在main目錄下建立一個jni文件夾

  • 4.打開Android Studio的terminal,使用cd定位在Android工程的app目錄下輸入

javah -d jni -classpath ..\..\build\intermediates\classes\debug com.xxxxxxx.xxx.JniFunction
//切記debug和com之間有空格
  • 5.在jni文件夾中就生成了com_learnncode_learnndk_JniFunction.h的頭文件

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

#ifndef _Included_com_learnncode_learnndk_JniFunction
#define _Included_com_learnncode_learnndk_JniFunction
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_learnncode_learnndk_JniFunction
 * Method:    getJniString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_learnncode_learnndk_JniFunction_getJniString
  (JNIEnv *, jclass);

/*
 * Class:     com_learnncode_learnndk_JniFunction
 * Method:    addNumber
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_learnncode_learnndk_JniFunction_addNumber
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif
  • 6.在jni文件夾下新建C/C++ Source File,複製h頭文件中定義的函數實現函數內容。須要注意的是選擇新建.c文件而不是.cpp,另外記得多添加一個無用的c文件,否則編譯可能會出錯。

#include "com_learnncode_learnndk_JniFunction.h"
/*
 * Class:     com_learnncode_learnndk_JniFunction
 * Method:    getJniString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_learnncode_learnndk_JniFunction_getJniString
  (JNIEnv * env, jclass obj){
    return (*env)->NewStringUTF(env,"Hello Android NDK");
  }

/*
 * Class:     com_learnncode_learnndk_JniFunction
 * Method:    addNumber
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_learnncode_learnndk_JniFunction_addNumber
  (JNIEnv * env, jclass obj, jint a, jint b){
    return a + b;
  }
  • 7.在app build.gradle添加ndk配置

defaultConfig {
        applicationId "com.learnncode.learnndk"
        minSdkVersion 14
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        ndk{
            moduleName "JniFunction"  //設置庫(so)文件名稱
        }
    }
  • 8.在jni調用的地方添加如下內容

static {
        System.loadLibrary("JniFunction");
    }
//JniFunction就是build.gradle中NDK的文件名

新增內容補充16.10.21

  • 1.so文件的生成
    在app build.gradle中設置ndk生成so文件庫文件名

    ndk{
            moduleName "JniFunction"  //設置庫(so)文件名稱
            abiFilters "armeabi","armeabi-v7a","x86"
        }

clipboard.png

編譯項目後在項目目錄下ndk文件中就能看到生成的so文件

clipboard.png

ABI:指應用基於哪一種指令集來進行編譯,ABI總共有四種,分別是armeabi、armeabi-v7a、mips、x86,它們都是表示cpu的類型。
安卓支持三類處理器(CPU):ARM、Intel和MIPS。ARM無疑被使用得最爲普遍。Intel由於普及於臺式機和服務器而被人們所熟知,然而對移動行業影響力相對較小。MIPS在32位和64位嵌入式領域中歷史悠久,得到了很多的成功,可目前Android的採用率在三者中最低。

  • 2.Android studio2.2環境下目錄變化
    更新了Android Studio以後發現加載目錄發現了變化,原來的Jni文件放置在了單獨的文件目錄下

Project
clipboard.png

Android
clipboard.png

新增內容補充16.11.09

Android項目調用.so文件方法:在src/main/目錄下新建jniLibs文件夾把ndk abiFilters生成的so文件拷貝在此目錄下,再在build.gradle defultConfig中配置jniLibs路徑,看過其餘人寫的默認寫的是libs好像也是可運行的,這裏我仍是填上正式新建時的路徑

sourceSets.main{
            jniLibs.srcDirs  "src/main/jniLibs"
        }

結尾及成果展現

NDK開發環境的搭建算不上特別難,就是麻煩了些。以前看別人的教程說NDK r10b版本是比較穩定的,我使用的是r12b也能編譯成功,目前看來仍是可使用的。這節先爲NDK開發開一個頭,其中也沒詳細講解關於NDK開發的語法等內容。學習NDK的道路仍是任重而道遠啊。附上google官方的NDK開發Demo實例
本節Demo項目地址
圖片描述

相關文章
相關標籤/搜索