Just My Life & My Work

Crashlytics loadLibrary

最近一個月,湧入上萬用戶使用我們家的 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。

參考:

隨意留個言吧:)~

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

標籤雲