Android Studio開發JNI - 第一個JNI程序

使用Android Sutdio創建一個JNI程序基本步驟如下:

  • 新建一個Android工程
  • 生成.c頭文件
  • 編寫實現native方法功能的cpp文件
  • NDK安裝與配置
  • 運行程序

新建一個Android工程

示例中,我新建了一個名爲LearnJni的Android工程。

project結構如下圖:
這裏寫圖片描述

在MainActivity中編寫示例代碼如下:

public class MainActivity extends AppCompatActivity {

    static {
        System.loadLibrary("myjni");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView = (TextView) findViewById(R.id.text_view);
        textView.setText(getJniMessage());
    }

    public native String getJniMessage();

}

在靜態初始化塊中,我們調用System.loadLibrary("myjni") 來加載下面我們將會命名爲“myjni”的jni庫文件。並在程序中定義並使用了getJniMessage()本地方法。

生成.c頭文件

使用Android Studio自帶的Terminal或你計算機系統的Terminal,將當前目錄切換到<Project>\app\src\main\java下。然後執行如下命令:
這裏寫圖片描述

執行過該命令後,將在<Project>\app\src\main\目錄下創建一個名爲jni的文件夾,並在其中生成與MainActivity對應的c頭文件。執行完該命令後的project結構如下:
這裏寫圖片描述

生成的.c頭文件內容如下:

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

#ifndef _Included_com_example_sunxiaodong_learnjni_MainActivity
#define _Included_com_example_sunxiaodong_learnjni_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_sunxiaodong_learnjni_MainActivity
 * Method:    getJniMessage
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_sunxiaodong_learnjni_MainActivity_getJniMessage
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

編寫實現native方法功能的cpp文件

<Project>\app\src\main\jni下,新建一個cpp文件。將上一步生成的.c頭文件中的內容,拷貝到該cpp文件中。並根據具體需要的功能,實現相應native方法。示例中,我新建了一個名爲MyJniMessage.cpp的文件,具體實現內容如下:

//
// Created by sunxiaodong on 16/6/14.
//
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>
#ifndef LOG_TAG
#define LOG_TAG "MY_JNI_LOG"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#endif
/* Header for class com_example_sunxiaodong_learnjni_MainActivity */

#ifndef _Included_com_example_sunxiaodong_learnjni_MainActivity
#define _Included_com_example_sunxiaodong_learnjni_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_sunxiaodong_learnjni_MainActivity
 * Method:    getJniMessage
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_sunxiaodong_learnjni_MainActivity_getJniMessage
  (JNIEnv *env, jobject jObj) {
    LOGE("jni輸出的log");
    return (*env).NewStringUTF("我的第一個Jni");
}

#ifdef __cplusplus
}
#endif
#endif

作爲示例,getJniMessage()方法的native實現很簡單,僅輸出一條log,並創建一個字符串。

通過上面步驟,我們Jni示例程序的編寫已經完成,接下來,執行“Build->Make Project”,如果你之前沒有安裝NDK,則會有以下“Messages Gradle Build”提示:

Error:Execution failed for task ':app:compileDebugNdk'.   
> NDK not configured.   
Download the NDK from http://developer.android.com/tools/sdk/ndk/.Then add ndk.dir=path/to/ndk in local.properties. 

接下來,下載安裝NDK,並進行相關配置。

NDK安裝與配置

進入SDK Manager,按下圖所示,安裝NDK。

這裏寫圖片描述

在local.properties中,指定ndk路徑。

這裏寫圖片描述

<Project>\app\build.gradle文件中,添加ndk配置。

這裏寫圖片描述

以上配置代碼指定的so庫名稱爲myjni,鏈接時使用到的庫,及最終輸出指定三種abi體系結構下的so庫。

完成如上的NDK的安裝和配置,再次執行“Build->Make Project”,則可能會有以下“Messages Gradle Build”提示:
這裏寫圖片描述

如果出現該錯誤,則gradle.properties中添加android.useDeprecatedNdk=true。

執行“Build->Make Project”成功後,會在<Project>\app\build\intermediates\下生成如下.so文件:
這裏寫圖片描述

運行程序

運行該Android示例程序後,會輸出一條如下log:
這裏寫圖片描述

程序運行後,界面展示如下:
這裏寫圖片描述

示例源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章