1. 程式人生 > >Android Studio NDK及so檔案開發 以及常見錯誤

Android Studio NDK及so檔案開發 以及常見錯誤

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := demo
LOCAL_SRC_FILES := demo.cpp
include $(BUILD_SHARED_LIBRARY)

android中用到的so檔案是一個c/c++的函式庫。在android的JNI中,要先將相應的C語言打包成so庫,然後匯入到lib資料夾中供java呼叫。

概覽:

一、Android Studio NDK配置

二、so庫開發

三、呼叫so藉口,實現藉口輸出

四、遇到問題

一、Android Studio NDK配置

1、進入Android studio --> 建立工程-->右鍵當前工程 => Open Moudle Setting => Android SDK location -->配置Android NDK location

2、配置環境變數

找到安裝的ndk-bundle路徑配置系統環境變數,如我的在D:\Android\AndroidSDK\ndk-bundle可以在系統環境變數中配置PATH=...;D:\Android\AndroidSDK\ndk-bundle    開啟CMD視窗,若已經開啟需要重新開啟。

如下表示已經成功配置:

C:\Users\Administrator>ndk-build

    Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
D:\Android\AndroidSDK\ndk-bundle\build\\..\build\core\build-local.mk:151: *** An
droid NDK: Aborting    .  Stop.

二、建立so檔案

工程目錄建立需要呼叫native函式的.java檔案,如下:

package clove.hellojni;

public class HelloJIN {
    static {
        System.loadLibrary("demo");
    }
    public native String helloJNI();
}
進入類檔案位置目錄:javac編譯HelloJIN.java,生成HelloJIN.class

進入包目錄前已經目錄:javah -jni 包名.類名

生成c/c++依賴的.h檔案xx_nn.h

app目錄新建jni目錄:jni目錄下新建.c/.cpp檔案,實現native藉口,如demo.cpp

 #include <jni.h>
 #include <stdio.h>
 #include "D:\AndroidStudioProjects\HelloJNI\app\src\main\java\clove_hellojni_HelloJIN.h"

JNIEXPORT jstring JNICALL Java_clove_hellojni_HelloJIN_helloJNI(JNIEnv *env, jobject thiz){
    return env->NewStringUTF((char *)"Hello from JNI !");
}
jni目錄建立編譯檔案Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := demo
LOCAL_SRC_FILES := demo.cpp
include $(BUILD_SHARED_LIBRARY)
注意實現native藉口檔案為.c是需要LOCAL_SRC_FILES := demo.cpp改為LOCAL_SRC_FILES := demo.c

進入app目錄:命令ndk-build進行編譯.so檔案,編譯完成後生成libdemo.so檔案在libs目錄下。

三、呼叫so介面:

在app的build.gradle的android節點下設定:

sourceSets{
        main{
            jniLibs.srcDirs = ['libs']
        }
    }
在呼叫native介面java檔案實現:
<pre name="code" class="java">package clove.hellojni;

/**
 * Created by clove.xie on 2016/9/10.
 */
public class HelloJIN {
    static {
        System.loadLibrary("demo");
    }
    public native String helloJNI();
}

注意在實現native介面是c/cpp的區別,

四、注意問題:

error: base operand of '->' has non-pointer type '_JNIEnv'  

呼叫的程式碼這麼來寫: //return (*env)->NewStringUTF(env, "Hello from JNI !");//如果是用C語言格式就用這種方式
      //return env->NewStringUTF((char *)"Hello from JNI !");//C++用這種格式