android studio搭建JNI開發環境

1.明確爲何要學習JNI

  • JNI是Java Native Interface的縮寫,它提供了若干的API實現了Java和其他語言的通信(主要是C&C++)。從Java1.1開始,JNI標準成爲java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI一開始是爲了本地已編譯語言,尤其是C和C++而設計的,但是它並不妨礙你使用其他編程語言,只要調用約定受支持就可以了。使用java與本地已編譯的代碼交互,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的。例如,使用一些舊的庫,與硬件、操作系統進行交互,或者爲了提高程序的性能。JNI標準至少要保證本地代碼能工作在任何Java 虛擬機環境。
  • Java開發要用到JDK,Android開發要用到SDK,那我們在Android中要進行native開發,也要用到它對應的工具包,即NDK。通俗的來講,NDK就是幫助我們可以在Android應用中使用C/C++來完成特定功能的一套工具。 NDK的作用有很多,我們簡單的列舉兩個,比如:
    1.首先NDK可以幫助開發者“快速”開發C(或C++)的動態庫。
    2.其次,NDK集成了“交叉編譯器”。使用NDK,我們可以將要求高性能的應用邏輯使用C開發,從而提高應用程序的執行效率.
    arm結構 :主要在移動手持、嵌入式設備上。我們的手機幾乎都是使用的這種CUP架構。
    x86結構 : 主要在臺式機、筆記本上使用。如Intel和AMD的CPU 。
    MIPS架構:多用在網關、貓、機頂盒等設備

2.NDK下載:https://developer.android.google.cn/ndk/downloads 根據操作系統選擇

3.as配置ndk:file->Project Structure->SDK Location->Android NdK Location寫入下載解壓後的ndk路徑

4.jni開發流程

  1. 在MainActivity類中聲明函數jniSay(native關鍵字):
public class MainActivity extends AppCompatActivity {

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

   }

   public native String jniSay(String str);

   public void click(View view) {
       System.loadLibrary("JniSay");
       String str=jniSay("hello word");
       Toast.makeText(this,str,Toast.LENGTH_LONG).show();
   }
}
  1. 在main目錄下新建文件夾jni
  2. 在jni下新建JniSay.c文件
  3. 進到main/java裏使用命令:
D:\android\jniTest\app\src\main\java>javah -jni com.zcx.myapplication.MainActivity
  1. 打開生成的com_zcx_myapplication_MainActivity.h文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_zcx_myapplication_MainActivity */

#ifndef _Included_com_zcx_myapplication_MainActivity
#define _Included_com_zcx_myapplication_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     com_zcx_myapplication_MainActivity
* Method:    jniSay
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_zcx_myapplication_MainActivity_jniSay
 (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif
  1. 將下述代碼複製到JniSay.c文件裏
#include<stdlib.h>
#include<jni.h>

JNIEXPORT jstring JNICALL Java_com_zcx_myapplication_MainActivity_jniSay(JNIEnv * env,jstring str){
   char* c="I am from c....";
   return (**env).NewStringUTF(env,c);
}

jstring對應java中的string類
jstring本質還是void*類型的指針(在jni.h裏申明的所以要導入)
7. 在jni目錄下新建Android.mk (https://developer.android.google.cn/ndk/guides/android_mk)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE:= JniSay
LOCAL_SRC_FILES:= JniSay.c
#LOCAL_CFLAGS:= -Wall -Wextra -Werror
#LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH)
#LOCAL_EXPORT_LDLIBS:= -ldl
include $(BUILD_SHARED_LIBRARY)
  1. 在jni目錄下新建Application.mk (https://developer.android.google.cn/ndk/guides/application_mk)可選
  2. 進入jni目錄執行命令:ndk-build JniSay
  3. 在項目gradle.properties裏添加: android.useDeprecatedNdk=true
  4. 在app/build.gradle裏的defaultConfig節點添加:
defaultConfig {
        applicationId "com.zcx.myapplication"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        ndk {
            moduleName "JniSay"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDir 'libs'
        }
    }
  1. 將main/obj/local下的文件複製到 項目/libs下
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章