小菜在一個曆史項目中接入了 Flutter Module 并采用 FlutterBoost 作為 Platform Channel 橋接;但實際開發遇到很多問題,僅記錄兩個印象深刻的小問題;
問題一:.so 檔案混淆
問題分析
小菜的曆史項目使用的 NDK 是 armeabi 而接入 Flutter 之後需要使用 armeabi-v7a,小菜在項目中添加 armeabi-v7a 對應的 .so 檔案,使 NDK 支援 armeabi-v7a,小菜測試直接允許或 debug 包是正常的,而 release 包直接崩潰,提示 libc.so 找不到;
** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Xiaomi/kenzo/kenzo:6.0.1/MMB29M/V8.5.4.0.MHOCNED:user/release-keys'
Revision: '0'
ABI: 'arm'
pid: 2380, tid: 2380, name: com.ace.test >>> com.ace.test <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: '[FATAL:flutter/shell/platform/android/library_loader.cc(24)] Check failed: result.
'
r0 00000000 r1 0000094c r2 00000006 r3 f748cb7c
r4 f748cb84 r5 f748cb34 r6 00000002 r7 0000010c
r8 f517f90c r9 ab645148 sl 00100019 fp ffc3c58c
ip 00000006 sp ffc3c3e8 lr f7208f5d pc f720b358 cpsr 400d0010
backtrace:
#00 pc 00044358 /system/lib/libc.so (tgkill+12)
#01 pc 00041f59 /system/lib/libc.so (pthread_kill+32)
#02 pc 0001ba6f /system/lib/libc.so (raise+10)
#03 pc 00018c11 /system/lib/libc.so (__libc_android_abort+34)
#04 pc 000167d0 /system/lib/libc.so (abort+4)
#05 pc 0014540b /data/app/com.ace.test-1/lib/arm/libflutter.so (offset 0x122000)
#06 pc 0013a091 /data/app/com.ace.test-1/lib/arm/libflutter.so (offset 0x122000) (JNI_OnLoad+764)
#07 pc 00250143 /system/lib/libart.so (_ZN3art9JavaVMExt17LoadNativeLibraryEP7_JNIEnvRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEP8_jobjectPS9_+1174)
#08 pc 002c2027 /system/lib/libart.so (_ZN3artL18Runtime_nativeLoadEP7_JNIEnvP7_jclassP8_jstringP8_jobjectS5_+178)
#09 pc 727b02c5 /data/dalvik-cache/arm/system@[email protected] (offset 0x2465000)

方案解決
既然隻有 release 包有問題,很大可能是混淆檔案有問題;小菜查了一些資料将涉及到的 Flutter 檔案免混淆,因為小菜對 NDK 等研究還很淺,是以僅提供列出方案;之後打包測試結果正常應用;
#Flutter Wrapper
-dontwarn io.flutter.**
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
問題二:FlutterBoost 導緻 release 包崩潰
問題分析:
小菜在內建 FlutterBoost 之後,打包 release 包測試時,發現有些手機進退兩次應用就會崩潰,小菜也是很崩潰,抓到 Log 提示 Surface 在銷毀時空指針;
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.Surface.release()' on a null object reference
at io.flutter.embedding.android.FlutterTextureView.disconnectSurfaceFromRenderer(SourceFile:198)
at io.flutter.embedding.android.FlutterTextureView.detachFromRenderer(SourceFile:161)
at com.idlefish.flutterboost.XFlutterView.detachFromFlutterEngine(SourceFile:713)
at com.idlefish.flutterboost.containers.FlutterSplashView.onDetach(SourceFile:196)
at com.idlefish.flutterboost.ContainerRecord.onDisappear(SourceFile:115)
at com.idlefish.flutterboost.containers.FlutterActivityAndFragmentDelegate.onPause(SourceFile:200)
at com.idlefish.flutterboost.containers.FlutterFragment.onPause(SourceFile:280)
at androidx.fragment.app.Fragment.performPause(SourceFile:2879)
at androidx.fragment.app.FragmentStateManager.pause(SourceFile:373)
at androidx.fragment.app.FragmentManager.moveToState(SourceFile:1204)
at androidx.fragment.app.FragmentManager.moveToState(SourceFile:1354)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(SourceFile:1432)
at androidx.fragment.app.FragmentManager.moveToState(SourceFile:1495)
at androidx.fragment.app.FragmentManager.dispatchStateChange(SourceFile:2617)
at androidx.fragment.app.FragmentManager.dispatchPause(SourceFile:2585)
at androidx.fragment.app.FragmentController.dispatchPause(SourceFile:280)
at androidx.fragment.app.FragmentActivity.onPause(SourceFile:419)
at com.test.ace.BaseActivity.onPause(SourceFile:302)
at com.test.ace.MainActivity.onPause(SourceFile:360)
at android.app.Activity.performPause(Activity.java:6415)
at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1312)
at android.app.ActivityThread.performNewIntents(ActivityThread.java:2588)
at android.app.ActivityThread.handleNewIntent(ActivityThread.java:2599)
at android.app.ActivityThread.access$1800(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1447)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:5527)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
小菜分析查閱 FlutterBoost 源碼,在 FlutterTexture -> disconnectSurfaceFromRenderer() -> renderSurface 中銷毀時報錯;
private void disconnectSurfaceFromRenderer() {
if (flutterRenderer == null) {
throw new IllegalStateException("disconnectSurfaceFromRenderer() should only be called when flutterRenderer is non-null.");
}
flutterRenderer.stopRenderingToSurface();
renderSurface.release();
renderSurface = null;
}
小菜采用的是 Fragment 方式,而使用的方法就是官網中使用的 NewEngineFragmentBuilder() 方式,并沒有對生命周期有變更操作;
mFragment = new FlutterFragment.NewEngineFragmentBuilder().url("url").build();
小菜研究了好幾天也沒有搞明白,後來請教了一個同僚,無意間想到是不是版本不一緻導緻的;小菜目前采用的 FlutterBoost 是 v1.12.13 而本地 Flutter 版本是 v1.14.6:
flutter --version
方案解決:
小菜猜測可能是 FlutterBoost 未對 Flutter 高版本進行适配,于是小菜準備統一版本嘗試一下,即固定目前 project 的 Flutter 版本為 v1.12.13+hotfix.8;
flutter version v1.12.13+hotfix.8
小菜 clean 之後心驚膽戰的打 release 包嘗試,在各手機上進行安裝測試,一切正常,目前沒有出現閃退問題,基本定位為使用的 FlutterBoost 和 Flutter 環境不一緻造成的;
flutter clean
小菜對于 Flutter 的實際開發還很欠缺,遇到很多意想不到的問題,剛處于探索學習階段,如有錯誤請多多指導!
來源: 阿策小和尚