Android中so文件加載問題

前言-現在市面主流的手機架構

  • x86/x86_64:這種架構手機包含由Intel提供的指令集轉碼工具,實現了對arm的兼容,使用這種架構的手機市場佔有率很低。
  • mips/mips64:極少手機使用這種架構,有興趣可以自行百度。
  • armeabi ARM v5:相當老舊的版本,缺少對浮點數計算的硬件支持,需要大量計算時有性能瓶頸。
  • armeabi-v7a ARM v7:現在市面上主流版本,比如驍龍、麒麟處理器等大部分處理器採用這種架構。
  • arm64-v8a ARM v8 :64位的

問題1 cannot find “libxxx.so”

原因分析

一. 存放路徑不對,默認是放在src/jniLibs,而手動指定目錄後放錯了位置。

Android Studio一般把so文件放在jnilibs目錄下對應的框架名文件夾下(比如:armeabi、armeabi-v7a、arm64-v8a)。你也可以自己定義jni的目錄。

如下在工程級別的gradle下設置了路徑myJniLibs,那文件就要放到這個目錄下對應架構文件裏。

 sourceSets.main {
        jniLibs.srcDirs = ['src/main/myJniLibs']
    }

二. 由於不同框架下的so文件名稱不同,造成的找不到。
一般情況下,一組so文件名稱都是一樣的,放在不同的架構文件夾下。使用的時候直接通過一行代碼就能加載。

  //放到庫文件的so文件→libxxx.so
  System.loadLibrary("xxx");

但是對於情況2則要手動判斷cpu架構,以ffmpeg的so文件爲例,代碼如下

try {
		  //判斷cpu架構,拿到不同的so文件
          if (Build.class.getField("CPU_ABI").get(null).toString().startsWith("arm64-v8a")) {
              System.loadLibrary("ffmpeg-squirrel-arm64-v8a");
          } else {
              System.loadLibrary("ffmpeg-squirrel-armeabi-v7a");
          }
      } catch (IllegalAccessException e) {
          e.printStackTrace();
      } catch (NoSuchFieldException e) {
          e.printStackTrace();
      }

三. 32位系統的手機不會報錯,64位系統的手機報錯

“xxx.so” is 32-bit instead of 64-bit

分析:項目中使用了多個第三方的sdk。有的sdk提供了32位和64位的so文件,有的sdk只提供了32位的so文件。當使用64位手機去拿某個只提供了32位so文件sdk的庫文件的時候,由於只會去64位架構文件下找,但是找不到(64位的文件夾存在,但是裏面沒有我要的這個so文件)。

解決辦法:

  1. 把64位的文件夾全刪了,因爲向下兼容,就回去32位文件下找。
  2. 自己編譯64位的so,或者叫第三方提供。(一般源碼找不到,就只能找第三方弄)

問題2 java.lang.UnsatisfiedLinkError: JNI_ERR returned from JNI_OnLoad

加載so文件的代碼所在的類,需要和so文件實現所在的類是同一個包名,不然它找不到so文件中native方法的實現。

出錯原因:打so包的那個ndk-build的配置文件的packageName和加載so文件那個類的包名不一致。

後話-打出一個so文件

不管是Eclipse還是AndroidStudio,只要配置了ndk的環境變量(Linux系統忽略,Windows在系統變量的Path裏添加你的ndk-bundle文件目錄),就可以打出so。

  1. 打開命令行。切到jni所在目錄。
  2. Android.mkApplication.mk2個文件配置一下。
  3. 命令行輸入ndk-build命令。

例子
1、Application.mk

//打出所有類型的so,也可以寫幾個你需要的  APP_ABI := armeabi,armeabi-v7a,arm64-v8a
APP_ABI := all 

2、Android.mk
這個文件比較複雜,就不貼了。大概就是定義路徑的變量,so包名稱,本地src路徑下的一些".c"文件等。有興趣的可以自行百度。

發佈了28 篇原創文章 · 獲贊 17 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章