【Flutter 專題】81 圖解 Android Native 整合 FlutterBoost 小嚐試 (三)|8月更文挑戰

阿策小和尚發表於2021-08-07

      “這是我參與8月更文挑戰的第7天,活動詳情檢視: 8月更文挑戰” juejin.cn/post/698796…

      小菜在一個歷史專案中接入了 Flutter Module 並採用 FlutterBoost 作為 Platform Channel 橋接;但實際開發遇到很多問題,僅記錄兩個印象深刻的小問題;

問題一:.so 檔案混淆

問題分析

      小菜的歷史專案使用的 NDKarmeabi 而接入 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@framework@boot.oat (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();
複製程式碼

      小菜研究了好幾天也沒有搞明白,後來請教了一個同事,無意間想到是不是版本不一致導致的;小菜當前採用的 FlutterBoostv1.12.13 而本地 Flutter 版本是 v1.14.6

flutter --version
複製程式碼

方案解決:

      小菜猜測可能是 FlutterBoost 未對 Flutter 高版本進行適配,於是小菜準備統一版本嘗試一下,即固定當前 projectFlutter 版本為 v1.12.13+hotfix.8

flutter version v1.12.13+hotfix.8
複製程式碼

      小菜 clean 之後心驚膽戰的打 release 包嘗試,在各手機上進行安裝測試,一切正常,目前沒有出現閃退問題,基本定位為使用的 FlutterBoostFlutter 環境不一致造成的;

flutter clean
複製程式碼


      小菜對於 Flutter 的實際開發還很欠缺,遇到很多意想不到的問題,剛處於探索學習階段,如有錯誤請多多指導!

來源: 阿策小和尚

相關文章