如何在 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 └── resUnsatisfiedLinkError: 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參考:
- Develper - Android NDK Preview
- Developer - NDK Setup
- Developer - JNI Tips
- Developer - Create Hello-JNI with Android studio
- Developer - Sample: hello-jni
- GitHub - googlesamples/android-ndk
- StackOverflow - How to include *.so library in Android Studio?
- StackOverflow - Using existing shared library (.so) in Android application
- StackOverflow - System.loadLibrary(…) couldn’t find native library in my case
- StackOverflow - How do I view the list of functions a Linux shared library is exporting?
- blog - The new NDK support in Android Studio
- blog - java.lang.UnsatisfiedLinkError: Native method not found 三種可能解決方案
- blog - Android動態加載補充 加載SD卡中的SO庫 by kaede
來自: http://li2.me/2016/04/how-to-include-and-use-so-library-in-android-studio.html