转载

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

需要 3 步:

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等)中的路径,以及 armeabiarmeabi-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");     } } 

这篇开发文档 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 

参考:

  • 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
正文到此结束
Loading...