JNI學習與NDK入門

一、JNI 學習

JNI(Java Native Interface,JAVA原生接口),使用JNI可以使Java代碼和其他語言寫的代碼(如C/C++代碼)進行交互。JNI 是一個協議,虛擬機通過 這個協議用來溝通java代碼和外部的本地代碼(c/c++).
1.生成頭文件
新建JNIDemo.java文件,然後聲明native方法 public native void testHello();

Javac JNIDemo //生成.class文件,然後//退回到classes一級目錄
> cd  /home/gms/Project/AutoClick/app/src/main/java
> javah com.example.autoclick.JNIDemo;

package com.example.autoclick;

public class JNIDemo {
    static{
        System.load("/home/gms/Project/AutoClick/app/libs/libjnidemo.so");
    }
    public native void testHello();
    public static void main(String[] args){
       // System.loadLibrary("libjnidemo");

        JNIDemo jniDemo = new JNIDemo();
        jniDemo.testHello();
    }
}

2. 編寫C文件

頭文件中testHello()對應的函數:Java_com_example_autoclick_JNIDemo_testHello ;

生成規則:Java_ + 包名(com.example.autoclick) + 類名(JNIDemo) + 接口名(testHello )

java虛擬機就可以在java類調用testHello接口的時候自動找到這個C實現的Native函數調用。
創建JNIDemo.cpp,# include "*.h",然後複製h文件中函數到cpp file;

3. 編譯C文件

g++ -I /usr/lib/jvm/java-8-openjdk-amd64/include  -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux JNIDemo.cpp -fPIC -shared -o libjnidemo.so

4.使用SO

 System.load("/home/gms/Project/AutoClick/app/libs/libjnidemo");
5.run app
javac JNIDemo.java;

二、NDK入門

Android NDK(Native Development Kit) 是一系列工具的集合,幫助開發者快速開發 C 或 C++庫.。環境搭建

1.下載組件 從菜單欄依次選擇 Tools > SDK Manager ->sdk tool  勾選NDK;CMake;LLDB,點擊 Apply,點擊Finsh.

 2.配置NDK環境變量

subl ~/.bashrc添加

export NDK_HOME=/home/gms/Android/Sdk/ndk/21.0.6113669

export PATH=$PATH:$NDK_HOME

source ~/.bashrc  

3.配置項目NDK路徑

project File -- Project Structure -- SDK Location--Select default NDK

4.創建頭文件,編寫C文件

5.配置mk與編譯項目(兩種方式)

(1)配置gradle

在app下的gradle文件下添加

android { defaultConfig{

        ndk {
            moduleName "jnidemo"
            ldLibs "log", "z", "m"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }
}

sourceSets { main { jni.srcDirs = ['src/main/jni', 'src/main/jni/'] } }

}

(2)生成so

rebuild生成.so文件 build->rebuild project

(3)複製so

在main文件夾下建立 jinLIB文件夾 把.so按文件夾複製進去或者修改sourceSets

    sourceSets {
        main {
            manifest.srcFile 'src/main/AndroidManifest.xml'
            jni.srcDirs = [] //屏蔽掉默認的jni編譯生成過程
            jniLibs.srcDirs = ['src/main/libs/']
        }
    }

app.gradle defaultConfig:
        ndk {
            ldLibs "log", "z", "m"
            abiFilters "armeabi-v7a"
        }
./build/intermediates/merged_jni_libs/debug/out/libjnidemo.so

創建mk文件

.編寫Android.mk文件  

LOCAL_PATH := $(call my-dir) #編譯時的目錄  

include $(CLEAR_VARS) #清除之前的一些系統變量

  LOCAL_MODULE    := JNITest #編譯生成的so庫的名稱

LOCAL_SRC_FILES := hello_jni.c #源文件      

include $(BUILD_SHARED_LIBRARY) #指明要編譯成動態庫

編寫 Application.mk     

APP_ABI := all  

.Ndk編譯生成動態庫  

在jni目錄執行 $ ndk-build  

生成庫文件所在目錄:libs/*/JNITest .so,因爲Application.mk中配置all會生成各種架構下的so文件

5.Java代碼load 動態庫.調用native代碼  ·  通過點擊 Run 圖標 編譯並運行應用。

Gradle 會以依賴項的形式添加 CMake 或 ndk-build 進程,用於編譯原生庫並將其隨 APK 一起打包。  

在app 下的gradle文件下添加(配置so庫)

app.gradle android:     sourceSets {         main {             jniLibs.srcDirs = ['src/main/libs/']//so路徑         }     }

https://developer.android.google.cn/studio/projects/add-native-code.html?hl=zh_cn#create-cmake-script

參考

https://developer.android.google.cn/ndk/guides?hl=zh_cn

Android studio jni 入門helloworld https://blog.csdn.net/salute_li/article/details/52469214

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