首先這邊引用
環(huán)信SDK工程師
總結(jié)的出現(xiàn)這個問題的一些原因(稍作排版修改):
引用 / 環(huán)信SDK工程師分析 UnsatisfiedLinkError
前言
在開發(fā)項目的時候我們免不了使用一些第三方的庫來進行快速開發(fā)再膳,有些第三方庫只是簡單的一個jar
包访雪,但是有些使用了jni
開發(fā)婚度,因此會包含so
庫文件皱卓,這個時候如果不消息我們就會遇到一個錯誤:java.lang.UnsatisfiedLinkError
;
最近經(jīng)常遇到有開發(fā)者在問使用環(huán)信sdk
的時候出現(xiàn)這個錯誤恨搓;這里分享下問題原因以及解決方案院促;
相關(guān)信息
這里需要先解釋一下相關(guān)信息
hyphenatechatsdk
提供的指令集類型僅提供armeabi-v7a
、arm64-v8a
斧抱、x86
三種;
armeabi
和armeabi-v7a
是相近似的指令集常拓,v7a
是增強型指令集,運行速度辉浦,效率均有所提高弄抬,他們都是32
位指令,并且兼容宪郊;arm64-v8a
對應(yīng)arm64
位指令集掂恕;
arm64
位策略和intel IA32
不一樣:intel64
位指令是兼容intel32
位指令,intel32
位指令編譯的程序可以直接在intel64
位機器上運行弛槐;但是arm
不是懊亡,arm64
位和arm32
位是彼此獨立的指令系統(tǒng),不兼容乎串;arm
這樣設(shè)計的原因是因為運行在嵌入式上店枣,設(shè)計指標(biāo)更趨向于效率,和耗電考量;實際上arm64
位芯片上同時包含著arm64
指令處理器和arm32
位指令處理器鸯两,只不過兩個處理器彼此獨立闷旧;
導(dǎo)致產(chǎn)生UnsatisfiedLinkError
的幾個原因
影響鏈接的限制條件: armeabi
實際上可以運行在arm64
位機器上,只不過Google
增加了限制條件:
Android4.x
只要能找到so
钧唐,就可以運行忙灼,so
可以在armeabi
、armeabi-v7a
逾柿、arm64-v8a
缀棍,so
位置可以很隨意宅此;Android5.x
開始机错,檢查更加嚴(yán)格,會只有和芯片型號對應(yīng)目錄的so
會安裝到手機中父腕;
舉個例子:
開發(fā)環(huán)境下目錄結(jié)構(gòu)如下
libs/armeabi:libhyphenate.so libhyphenate_av.so
libs/armeabi-v7a:libmediadata.so
手機對應(yīng)的指令集是armeabi-v7a
弱匪,然后安裝到手機的只有libmediadata.so
;
Android6.x
下璧亮,檢查更加嚴(yán)格萧诫,有一條規(guī)則,之前測試有遇到枝嘶,現(xiàn)在不太確認帘饶;
libs/armeabi/: libhyphenate.so libhyphenate_av.so
libs/arm64-v8a
(沒有此目錄)
在arm64
位機器上也可以運行,但是作為開發(fā)者通常會依賴其他開發(fā)包群扶,比如baiduMap
及刻,也會用其他so
,不能讓所有開發(fā)者都刪掉libs/arm64-v8a
的目錄竞阐;不過開發(fā)者可以嘗試下刪除arm64-v8a
缴饭,只留armeabi
,這樣安裝包會很小骆莹,在各個平臺上也能運行颗搂;
Google
考量點是執(zhí)行速率,更流暢的用戶體驗幕垦,作為開發(fā)者丢氢,服務(wù)提供者,我們希望apk
盡可能小先改,對執(zhí)行速度要求不高疚察;armeabi
和armeabi-v7a
可以互換,現(xiàn)在市面上的手機很少有armeabi
的盏道,基本上是armeabi-v7a
或arm64
位的高端機器稍浆。查看手機芯片型號:
cat /proc/cpuinfo
, 仔細看一下打印信息,能夠看明白手機指令集,是32
位還是64
位衅枫。x86
目錄嫁艇,通常對應(yīng)虛擬機,很多開發(fā)者喜歡在genymotion
上開發(fā)調(diào)試弦撩,這個就對應(yīng)86
步咪,x86
和前面說的intel IA32
是一回事,所以只提供32
位的益楼,也能在x86-64
位機器上運行猾漫;我們的
so
還依賴于libsqlite.so
,不過由于這個包從來沒有變化感凤,使用的是系統(tǒng)默認提供的/system/lib
悯周,在Android 6.x
及以下的平臺可以運行,Android7.x
執(zhí)行更嚴(yán)格的安全檢查陪竿,禁止使用系統(tǒng)目錄的內(nèi)容禽翼,所以如果希望在Android7.x
以上版本,需要把系統(tǒng)目錄的libsqlite.so
拷貝出來族跛,也放在自己app
對應(yīng)指令目錄下闰挡,由于目前Android7.x
市面上沒有機型,所以目前不在考慮范圍礁哄;mips
指令集的手機很少見长酗,聽說聯(lián)想有出過,沒見過;libs/armeabi/libhyphenate.so
和libs.without.audio/armeabi/libhyphenate.so
是不同桐绒,libs/armeabi/libhyphenate.so
會依賴于libs/armeabi/libhyphenate_av.so
夺脾,如果找不到會報java.lang.UnsatisfiedLinkError
;還有一個比較容易忽略的一點掏膏,現(xiàn)在我們的的項目一般都是引入好多個第三方庫劳翰,第六點也提到了使用
baiduMap
這點,就是當(dāng)一個項目引入多個庫馒疹,不同的庫有不同的so
文件夾佳簸,當(dāng)其中一個支持的比較少,但是另一個比較全時颖变,也會出現(xiàn)這樣的錯誤生均,解決方法就是不支持的so
文件夾刪除
舉個例子:
環(huán)信支持的指令集arm64-v8a
、armeabi-v7a
腥刹、x86
百度地圖支持的指令集arm64-v8a
马胧、armeabi
、armeabi-v7a
衔峰、x86
佩脊、x86_64
蛙粘、mips
、mips64
如果想在所有設(shè)備上都能運行威彰,需要把x86_64
出牧、mips
、mips64
這些刪除歇盼;
根據(jù)前邊所說可以保留armeabi
和armeabi-v7a
文件夾舔痕,然后復(fù)制armeabi-v7a
里的so
文件到armeabi
就行了
結(jié)語
所以如果大家再遇到這樣的問題,可以先根據(jù)以上信息排查下豹缀,無非就是某個庫的 so 文件放多了伯复,或者某個 so 庫的文件放少了,或者是 jar 包和 so 不匹配了邢笙,這些只要細心看下 ide 的日志提示啸如,很容易就解決,希望此篇文章能幫大家解決問題鸣剪,謝謝组底!
文筆有限,如果問題筐骇,歡迎指正 _~