在新的Android工程中调用已经编译好的so库文件代码

  依旧是Android,NDK,JNI相关的问题。
  照着ndk帮助的说明,运行<ndk>/samples目录下的hello-jni工程后,你一定想知道如何在自己的项目里调用别人已经编译好的.so库文件。于是新建一个Android工程,将hello-jni例子中ndk-build后的结果:libs文件夹(包括其下所有内容)拷贝到新建工程的根目录下,仿照hello-jni的代码,调用native方法:

   1: package com.my.SoTest;

   2:  

   3: import android.app.Activity;

   4: import android.os.Bundle;

   5: import android.widget.TextView;

   6:  

   7: public class SoTestActivity extends Activity {

   8:     /** Called when the activity is first created. */

   9:     @Override

  10:     public void onCreate(Bundle savedInstanceState) {

  11:         super.onCreate(savedInstanceState);

  12:         

  13:         TextView tv=new TextView(this);

  14:         tv.setText(stringFromJNI());

  15:         setContentView(tv);

  16:     }

  17:     public native String stringFromJNI();

  18:     static {

  19:         System.loadLibrary("hello-jni");

  20:     }

  21: }

  运行后,logcat记录以下错误:

No implementation found for native Lcom/my/SoTest/SoTestActivity;.stringFromJNI ()Ljava/lang/String;

java.lang.UnsatisfiedLinkError: stringFromJNI

  在hello-jni的代码注释里明确说明,UnsatisfiedLinkError错误是由于native代码中没有该方法的实现而引起的,但stringFromJNI这个方法,在c代码中是有的;前一个错误就比较明确了,是在Lcom/my/SoTest/SoTestActivity中去找这个方法实现的,打开hello-jni.c文件看看该函数头,其中有这样的字样:Java_com_example_hellojni_HelloJni_stringFromJNI,而com.example.hellojni恰好是例子工程的package name,HelloJni则是class的名称。也就是说,我们.so中函数声明涉及到的package name和class name与调用它的package name和class name不符。google一下印证了这个猜测,但提供现成解决办法的不多,总不能自己工程的package name必须和.so里的一样吧。
  搜索看到了一篇NDK的教程,Using NDK to Call C code from Android Apps(需翻墙),里面写明了在一个普通Android工程中,如何从零开始组装自己的native代码。大致的步骤是,首先写一个java类,里面声明一些需要实现native方法(函数签名即可),然后用javah命令来生成对应的header文件,里面的内容是自动生成的native函数声明,然后照着这个声明实现各个函数,最后编译,用最初的java类调用。
  受此启发,我们在拿到别人已经编译好的.so文件后,可首先新建一个java类,所在package的名称和class名称都与.so文件中函数签名提示的一致,在这个类中加入native方法的声明。这样在别处就可以用这个wrapper调用so库中的函数了。

One thought on “在新的Android工程中调用已经编译好的so库文件代码”

  1. sina

    我从新浪微博3.0.5beta1版本中反编译出libutility.so,然后根据里面的函数定义,使用相同的包名和类名,本地未安装NDK环境,为什么还是不能调用里面的方法?一调用getDecryptionString方法应用程序就会强制退出,求解。

Leave a Comment

Your email address will not be published. Required fields are marked *