分析Android :java.lang.UnsatisfiedLinkError: dlopen failed * is 32-bit instead of 64-bit


Crash 日志:

java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/com.ireader.plug.sdk/ireader_plugins/lib/armeabi/lib***.so"
 is 32-bit instead of 64-bit
        at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
        at java.lang.System.loadLibrary(System.java:1657)

問題分析:

首先看log, 報錯為:so打開失敗,因為lib***.so 是32位的so,而不是64位的。
補充:

Android 程序 運行起來,要么只加載32位的so, 要么只加載64 位的so. 是不能混合加載的。

常見的兩種情況如下:

第一種情況:

對於一個android程序,如果程序沒有用到任何so,假如程序跑在64位的手機上,虛擬機默認加載64位的so。這時候,如果你加載了32位的so,就會報錯。反之,如果程序跑在32位的手機上,虛擬機默認只加載32位的so.

可能有同學有疑問,既然我的程序里面沒有任何的so, 跑在了64位的手機上,這種情況下怎么會加載32位的so呢?我的程序里面是沒有so 的啊。沒錯,你的apk 里面是沒有任何的so,但是如果你的項目中使用了插件技術,插件apk 里面有32 位的so,這時候就會掛掉了。

解決方法:

在你的項目里面建立一個armeabi 的文件夾,里面放一個文件。文件名字叫做fix.so。這個so 可以是0kb,但是一定要有。這樣,程序跑在64位的手機上,發現你只有armeabi 的文件夾,那么就會使用32 位的虛擬機,這時候,加載你插件里面的so,就不會有問題了。

第二種情況:

如果程序里面有so, 並且有arm64-v8a 或者x64 的文件夾,也有armeabi 的文件夾,運行在64位的手機上,會默認使用arm64-v8a 或者x64 文件夾里面的so. 這時候,如果有些so 沒有arm64-v8a ,就會報錯找不到so。 雖然你在armeabi 文件夾里面有。

如果是這種情況,那么直接把 arm64-v8a 的so 刪除掉,只留下armeabi 的so。 因為armebai 兼容所有類型的處理器。當然你也可以把缺少的64位的so 編譯一下。

我們項目具體場景:

我們是做插件sdk 給第三方接入的。我們會讓第三方接入一個apk文件,里面只有armeabi 的so.
還有一個libmerge.so 用於插件增量更新。但是有些廠商不願意動態更新,我們定的方案是如果不需要增量更新這個功能,程序里面可以沒有libmerge.so

早期的時候,手機還都是32位的,所以,沒有問題。但是現在都是64位的手機,有的廠商自己apk 沒有任何的so, 跑在64為手機上,上來就掛。java.lang.UnsatisfiedLinkError: dlopen failed * is 32-bit instead of 64-bit

他們反饋在有些手機會出現,有些手機可以正常運行。當然,可以運行的都是32位手機,不可以的都是64位的手機。

這時候,我們讓廠商放在armeabi 文件夾下一個fix.so。雖然是一個空文件,但是程序就可以跑起來。這樣,程序跑在64位的手機上,發現你只有armeabi 的文件夾,那么就會去加載32 位的so,這時候,加載你插件里面的so,就不會有問題了。

知識補充:

如何查看android cpu是32位還是64位?

adb shell getprop ro.product.cpu.abi

C:\Users\zy>adb shell getprop ro.product.cpu.abi
arm64-v8a


C:\Users\zy>adb shell getprop ro.product.cpu.abi
armeabi-v7a

可以看到手機默認的so 文件夾。arm64-v8a 是64位的。另外,一般手機內存超過4G 都是64位的,因為32支持的最大內存是4G.

參考:

https://www.cnblogs.com/janehlp/p/7473240.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM