Android Studio3.0 NDK配置與開發

smilestone322發表於2019-01-07

轉自: https://www.jianshu.com/p/433b2c93c6a7

前言

最近在學習JNI開發, 查閱<Android開發藝術探索>和網上很多文章, 發現很多知識都已經過時了, 經過一天的踩坑, 最終還是在官方文件中找到了解決方案, 下面就記錄下在Android Studio3.0中NDK的配置和開發

官方文件(需要科學上網)

向您的專案新增 C 和 C++ 程式碼

開發環境

系統: Mac os 10.13.3
軟體: Android Studio 3.0.1

下載 NDK 和構建工具

  1. 在開啟的專案中,從選單欄選擇 Tools > Android > SDK Manager。
  2. 點選 SDK Tools 標籤。
  3. 選中 LLDB、CMake 和 NDK 旁的核取方塊

     

    image.png

配置環境變數

在終端開啟環境變數配置檔案

vim ~/.bash_profile

新增環境變數

如果不熟悉環境變數的配置, 可以看一下這篇文章Mac環境變數設定

# Android
export ANDROID_HOME=~/Library/Android/sdk
export ANDROID_ADB=~/Library/Android/sdk/platform-tools
export ANDROID_NDK=~/Library/Android/sdk/ndk-bundle
export PATH=${PATH}:${ANDROID_HOME}:${ANDROID_ADB}:${ANDROID_NDK}

建立Android專案

1. 在類中宣告native方法

public class MainActivity extends AppCompatActivity{
    static {
        /**
         * 載入動態庫libhelloJni.so
         * 載入so檔案,不要帶上字首lib和字尾.so
         */
        System.loadLibrary("helloJni");
    }

    /**
     * 定義本地方法介面,這個方法類似虛方法,實現是用c或者c++實現的
     * @return
     */
    public native String get();
    public native void set(String str);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView = (TextView) findViewById(R.id.tv_hello);
        textView.setText(get());
        set("hello world form MainActivity");
    }
}

2. 實現Android專案中宣告的native方法

  1. 從 IDE 的左側開啟 Project 窗格並從下拉選單中選擇 Project 檢視。
  2. 導航到 您的模組 > src,右鍵點選 main 目錄,然後選擇 New > Folder > JNI Folder, 並點選 Finish。

     

    image.png

  3. 建立3個檔案hello.cpp, Android.mk, Application.mk
    hello.cpp
#include <jni.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 函式名規則: Java_包名_類名_方法名
 * @param env  表示一個指向JNI環境的指標, 可以通過它來方位JNI提供的介面方法
 * @param thiz 表示Java物件中的this
 * @return 
 */
jstring Java_com_qyh_hellojni_MainActivity_get(JNIEnv *env, jobject thiz) {
    printf("invoke get in c++\n");
    return env->NewStringUTF("Hello from JNI in helloJni.so !");
}

void Java_com_qyh_hellojni_MainActivity_set(JNIEnv *env, jobject thiz, jstring string) {
    printf("invoke set from C++\n");
    char* str = (char*)env->GetStringUTFChars(string,NULL);
    printf("%s\n", str);
    env->ReleaseStringUTFChars(string, str);
}

#ifdef __cplusplus
}
#endif

Android.mk

LOCAL_MODULE : 表示模組的名稱
LOCAL_SRC_FILES: 參與編譯的原始檔

# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := helloJni
LOCAL_SRC_FILES := hello.cpp

include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_ABI: 表示CPU的架構型別, 如armeabi, x86, mips

APP_ABI := armeabi

3. ndk-build編譯so庫

切換到jni目錄的父目錄, 即main目錄, 執行ndk-build命令

 

image.png

 

這時候, NDK會建立一個和jni目錄平級的目錄libs, libs下面存放的就是so庫

 

img


然後在app/src/main中建立一個名為jniLibs的目錄, 將生成的so庫複製到jniLibs目錄

image.png

4. 將 Gradle 關聯到您的原生庫

  1. 從 IDE 左側開啟 Project 窗格並選擇 Android 檢視。
  2. 右鍵點選您想要關聯到原生庫的模組(例如 app 模組),並從選單中選擇 Link C++ Project with Gradle
  3. 從下拉選單中,選擇 CMakendk-build
    1. 如果您選擇 CMake,請使用 Project Path 旁的欄位為您的外部 CMake 專案指定 CMakeLists.txt 指令碼檔案。
    2. 如果您選擇 ndk-build,請使用 Project Path 旁的欄位為您的外部 ndk-build 專案指定 Android.mk 指令碼檔案。如果 Application.mk 檔案與您的 Android.mk 檔案位於相同目錄下,Android Studio 也會包含此檔案。

      image.png

  4. 點選 OK。

最終在Gradle中生成以下設定

 

image.png

5. 編譯執行

image.png

6. 原始碼下載

GitHub



作者:樂意之至
連結:https://www.jianshu.com/p/433b2c93c6a7
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。

 

 

相關文章