在Android Studio中加载运行时库时出错

在Android Studio中加载运行时库时出错,android,android-studio,runtimeexception,Android,Android Studio,Runtimeexception,在我的android项目中,我使用了一个外部jar库,它利用了运行库libiconv.so。我将库包含在项目的lib目录中。该库包含在以下目录HIRACY中的所有三种体系结构中 libs> armeabi>libiconv.so armeabi-v7a>libiconv.so x86>libiconv.so 但我得到了log cat记录的异常: 05-23 12:18:58.857 3081-3081/?

在我的android项目中,我使用了一个外部jar库,它利用了运行库libiconv.so。我将库包含在项目的lib目录中。该库包含在以下目录HIRACY中的所有三种体系结构中

libs>
armeabi>libiconv.so
armeabi-v7a>libiconv.so
x86>libiconv.so
但我得到了log cat记录的异常:

05-23 12:18:58.857    3081-3081/?                              E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.ExceptionInInitializerError
        at java.lang.Class.newInstanceImpl(Native Method)
        at java.lang.Class.newInstance(Class.java:1319)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
        at android.app.ActivityThread.access$600(ActivityThread.java:141)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5041)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.UnsatisfiedLinkError: Couldn't load libiconv.so from loader dalvik.system.PathClassLoader[dexPath=/data/app/com.tariq.buynow-1.apk,libraryPath=/data/app-lib/com.tariq.buynow-1]: findLibrary returned null
        at java.lang.Runtime.loadLibrary(Runtime.java:365)
        at java.lang.System.loadLibrary(System.java:535)
        at com.tariq.buynow.CameraActivity.<clinit>(CameraActivity.java:30)
我也试过了

static { System.loadLibrary("iconv"); }
这与gradle配置有关,因为我是Android Studio新手,还是错误源是其他原因?

System.loadLibrary()
在设备的lib目录中查找,而不是在应用程序中查找。要想做你想做的事情,你需要将lib从应用程序复制到手机的文件系统上,然后从那里加载。我建议将LIB放在/res/raw/中,并这样做:

try {
    // Point the input stream to the library in /res/raw
    InputStream is = context.getResources().openRawResource(R.raw.libiconv);
    // Create a BufferedInputStream from the InputStream
    BufferedInputStream bis = new BufferedInputStream(is);
    // Set the FileOutputStream to the app's data directory
    FileOutputStream fos = context.openFileOutput("libiconv.so", Context.MODE_PRIVATE);

    byte data[] = new byte[1024];
    int count;
    while ((count = bis.read(data, 0, 1024)) != -1) {
        fos.write(data, 0, count);
    }
    fos.close();
    bis.close();
    is.close();

    System.load(context.getFilesDir() + "/libiconv.so");

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException ie) {
    ie.printStackTrace();
}

这可能并不完全有效,但其基本要点应该是这样的。

我在尝试使用ZBar SDK时遇到了同样的问题。您很可能需要编辑build.gradle,以确保APK中包含本机库。这就是我解决问题的方法:

在build.gradle脚本中添加以下行

jniLibs.srcDirs=['libs']//将*.so复制到包中

在项目视图中,您必须可以看到:
Module/libs/ABI NAME/*.so

在最新版本的Android Studio上,您只需使用
src/main/jniLibs中的本机库,gradle将完成其余工作。
try {
    // Point the input stream to the library in /res/raw
    InputStream is = context.getResources().openRawResource(R.raw.libiconv);
    // Create a BufferedInputStream from the InputStream
    BufferedInputStream bis = new BufferedInputStream(is);
    // Set the FileOutputStream to the app's data directory
    FileOutputStream fos = context.openFileOutput("libiconv.so", Context.MODE_PRIVATE);

    byte data[] = new byte[1024];
    int count;
    while ((count = bis.read(data, 0, 1024)) != -1) {
        fos.write(data, 0, count);
    }
    fos.close();
    bis.close();
    is.close();

    System.load(context.getFilesDir() + "/libiconv.so");

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException ie) {
    ie.printStackTrace();
}