如何在 Android Studio 中包含 *.so library,并使用庫中定義的方法?

Step1 把 .so file 放到 Android Studio project 正確的路徑中

需要新建一個名為 jniLibs 文件夾,根據目標機器的 CPU-ABI 類型,把 .so file 放入對應的路徑下:

weiyi$ cd app/src/main/
weiyi$ tree -L 2
.
├── AndroidManifest.xml
├── java
├── jniLibs
│   ├── armeabi
│   │   └── libhello-jni.so
│   └── armeabi-v7a
│       └── libhello-jni.so
└── res

至于在其它編譯器(eclipse等)中的路徑,以及 armeabi 和 armeabi-v7a 的解釋,參考 StackOverflow - System.loadLibrary(…) couldn’t find native library in my case

.so file 需要通過 NDK tool 編譯 c/c++ 得到,可以從 android.googlesource.com 下載 libhello-jni.so 。

Step2 加載 .so library 并聲明 native method

Java 端實現加載 .so library:(HelloJni.java)

package com.example.hellojni;

public class HelloJni { public native String stringFromJNI();

static {
    System.loadLibrary("hello-jni");
}

} </pre>

這篇開發文檔 Developer - Sample: hello-jni 解釋了 native 關鍵字。

Step3 最后就可以調用 .so library native method 了

類似調用任何一個類的方法:

    HelloJni helloJni = new HelloJni();
    LOGD(TAG, helloJni.stringFromJNI());

可以看到 log: Hello from JNI ! 。而整個工程目錄應該是這樣:

weiyiWorkCell:main weiyi$ tree -L 5
.
├── AndroidManifest.xml
├── java
│   └── com
│       ├── example
│       │   └── hellojni
│       │       └── HelloJni.java
├── jniLibs
│   ├── armeabi
│   │   ├── libhello-jni.so
│   └── armeabi-v7a
│       ├── libhello-jni.so
└── res

UnsatisfiedLinkError: No implementation found

在 step2 時,假如把 native method 聲明在了一個 隨意命名 的 package 或者隨意命名的 java file 內,比如 com.example.hellojni21.HelloJni ,你會遇到如下 exception:

java.lang.UnsatisfiedLinkError:
No implementation found for java.lang.String com.example.hellojni21.HelloJni.stringFromJNI() tried
Java_com_example_hellojni21_HelloJni_stringFromJNI and
Java_com_example_hellojni21_HelloJni_stringFromJNI__

這是因為命名存在一個默認的規則。.so file 需要通過 NDK tool 編譯 c/c++ 得到,c/c++ 實現 native method 時,要按如下規則命名,以 libhello-jni.so 為例:

jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
規則如下:
Java_package_file_method(...)

所以,Java 端的包名、文件名、方法名就被規定好了,包名必須是 com_example_hellojni ,文件名必須是 HelloJni ,native method 聲明必須是 String stringFromJNI() 。

這篇開發文檔 Developer - Sample: hello-jni 描述了命名規則。

我們還可以通過命令行列出 shared library 中的方法:

weiyi$ nm -D libhello-jni.so
00000b90 T Java_com_example_hellojni_HelloJni_stringFromJNI

參考:

來自: http://li2.me/2016/04/how-to-include-and-use-so-library-in-android-studio.html 

 本文由用戶 EloBock 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!