最近一個月,湧入上萬用戶使用我們家的 App,特別是 Android 手機用戶佔了大部分。當然用戶一多,就會出現不預期的狀況,這在開發 App 是很普遍發生的狀況。
特別是 Android 系統,相比 iOS 較為不穩定,因為是開放系統,讓各家軟硬廠商有較多的彈性去調整系統。於是乎,會遇到不預期的崩潰狀況,是理所當然之事。

這次來記錄一下,Crashlytics 記錄最多崩潰的事件:FlutterJNI.loadLibrary。
崩潰事件關鍵字詞如下:
FlutterJNI.loadLibrary
java.lang.UnsatisfiedLinkError – dlopen failed: library “libflutter.so" not found

此圖表時間:5/11-6/9。最多爆發量是在 5/16-5/18,之後就是零星發生,直至今日,已經趨近於 0。
其實沒有特別做處理,但就不曉得為何發生量會減少?推測有可能的原因,是那些遇到此狀況的用戶不再使用了。🫣
.so 是什麼?
在 Android 開發中,.so 是指共享目標庫(Shared Object)檔,也被稱為動態連結庫或共享庫。它是一種二進制文件格式,用於包含已編譯的函數和代碼,可以供不同的應用程式進行動態連結和重用。
在開發中,Android 的原生程式碼一般使用 C、C++ 編寫,然後編譯生成一個動態鏈接庫,就是文件後綴為 .so 的 ELF 文件。so 文件是 unix(一個系統的名字)的動態連接庫,是一個二進製文件,作用相當於 Windows 下的 .dll 檔。
在 Andorid 中調用 so 都是通過 JNI 的方式調用。Android 中提供了相關的方法,loadLibrary 的作用就是加載這個動態鏈接庫,這樣後面的程式碼調用才能成功找到對應的原生函數。一般加載 so 的程式碼要寫到 static 塊中,因為靜態程式碼塊的執行時機非常早,比什麼構造函式、onCreate 都要早,在類加載的時候就被調用。
.so 文件通常包含了一個或多個函數的實現,這些函數可以被其他應用程式或庫使用。Android 應用程式使用 .so 文件作為庫,可以實現模塊化設計,促進代碼的重用和共享。這樣的設計可以減小應用程式的大小,同時提供了更好的代碼管理和維護。
在 Android 開發中,通常會使用 C/C++ 語言進行性能要求較高的任務,例如圖形處理、音視頻編解碼等。這些任務的代碼可以編譯為 .so 文件,然後在 Java 程式碼中使用 JNI(Java Native Interface)進行調用。這樣就可以在 Android 應用程式中結合 Java 和 C/C++ 代碼,發揮各自的優勢。
總結來說,Android .so 是一種共享目標庫文件格式,用於包含已編譯的函數和代碼,供 Android 應用程式進行動態連結和重用。
目前手機 CPU 的架構有哪些?
- armeabi:ARM 架構的默認選項,支持基於 ARM* v5TE 的設備,支持軟浮點運算,但不支持硬件輔助浮點運算,支持所有的 ARM* 設備。
- armeabi-v7a:armeabi-v7a 向下相容,在相容 armeabi 的基礎上,支持基於 ARM* v7 的設備,支持硬件FPU 指令,支持硬件浮點運算,目前大部分機器都屬於 armeabi-v7a。
- arm64-v8a:arm64-v8a 向下相容 armeabi 和 armeabi-v7a,最主要的區別在於 arm64-v8a 支持 64 位,在 MIPS64 架構上增加了ARMv7 架構中已經擁有的的 TrustZone 技術、虛擬化技術及 NEON advanced SIMD 技術等特性(ARM 收購 MIPS)。架構中包含兩個執行狀態:AArch32(也就是我們常說的 ARMv7)和 AArch64(ARMv8),也就是說 64 位的 ARM 處理器中同時包含著 32 位的 ARMv7 和 64 位的 ARMv8 兩種架構,直接導致每種架構所擁有的晶體管減半。
- x86:X86 構架是英特爾推出的一種複雜指令集,用於控制芯片的運行的程序,目前該構架的處理器已經廣泛運用在 PC 領域,由於 X86 構架的處理器芯片在性能上比較強勁,善於執行複雜工作。X86 構架屬於典型的 CISC,指令集豐富,指令不等長,善於執行複雜工作,更強調串行性能。x86 機器基本上可以使用 intel 的 libhounini 項目直接在 x86 機器上運行僅含 armeabi 的動態庫代碼,也就會說 x86 機器對 armeabi 也能夠相容,不過性能上會有些損耗。
- x86_64:英特爾推出的64位CPU架構,向下相容x86。
- mips/mips:64 MIPS是一種高性能的嵌入式 CPU 構架,其出發點是高性能,主要用於路由器等。
可能的解決方案
找尋檔案:android/app/build.gradle
避免構建 x86 構建,因為 flutter 不支持它們。
defaultConfig {
applicationId "com.your-project-name"
minSdkVersion 24
targetSdkVersion 33
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
}
和下列部分:
buildTypes {
release {
signingConfig signingConfigs.release
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
}
它還有助於在為 Play Store 構建發布版本之前運行 flutter upgrade 和 flutter clean。
參考:
隨意留個言吧:)~