Steps to Reproduce
1.在 flutterboost example工程 修改 “main dart”,
把tab_message修改调到example工程里面的NativeViewExample页面
`
tab_message': (settings, uniqueId) {
return PageRouteBuilder<dynamic>(
settings: settings,
pageBuilder: (_, __, ___) =>
NativeViewExample());
}
`
2. run example 工程起来 进入 “open flutter fragment page”
3. 切换到 朋友Tab 必崩
Flutter Boost Version
4.2.0
Target Platform:
Android
Target OS version/browser:
Android 10
Devices:
荣耀畅玩 9A
Logs
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:5327)
at android.view.ViewGroup.addView(ViewGroup.java:5156)
at android.view.ViewGroup.addView(ViewGroup.java:5096)
at android.view.ViewGroup.addView(ViewGroup.java:5069)
at io.flutter.plugin.platform.PlatformViewsController.attachToView(PlatformViewsController.java:747)
at io.flutter.embedding.android.FlutterView.attachToFlutterEngine(FlutterView.java:1215)
at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onCreateView(FlutterActivityAndFragmentDelegate.java:337)
at io.flutter.embedding.android.FlutterFragment.onCreateView(FlutterFragment.java:806)
at com.idlefish.flutterboost.containers.FlutterBoostFragment.onCreateView(FlutterBoostFragment.java:92)
at com.idlefish.flutterboost.example.tab.FriendFlutterFragment.onCreateView(FriendFlutterFragment.java:19)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:434)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:900)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8349)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
• Flutter version 3.3.3 on channel stable at /Users/liuyc/fvm/versions/3.3.3
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 18a827f393 (6 weeks ago), 2022-09-28 10:03:14 -0700
• Engine revision 5c984c26eb
• Dart version 2.18.2
• DevTools version 2.15.0
5条答案
按热度按时间brqmpdu11#
因为detachFromFlutterEngine是FlutterBoostFragment在onCreateView做的。
但是super.onCreateView(inflater, container, savedInstanceState) 里面最终会把当前engine的platformview attach上去的操作(也就导致了第二个tab 错误的把第一个tab的platformview再次attach,所以出问题了)
flutterEngine.getPlatformViewsController().attachToView(this)
FlutterBoostFragment
bksxznpy2#
目前BoostFragment中的时序如下:
这个时许中,会出现crash的其实有两个点:
上述问题的crash点出在1上,解决方法其实就是两次
attachEngine
中间添加一次detachEngine
。但时机不好控制,所以基于目前没有PlatformView
的情况下,能够正常运行,那么一个折中的方案就是,在Fragment2attachEngine
之前,把PlatformView
从Fragment1的flutterView
中移除掉。但一般无法直接获取到Fragment1中的
flutterView
,所以这里可以通过继承PlatformViewsController
的方法来实现:然后在构建FlutterEngine的地方使用
FlutterBoostPlatformViewsController
代替PlatformViewsController
。最后在
FlutterBoostFragment
的onCreateView
方法开始调用removePlatformWrapperOrParents
把PlatformView
给移掉。这种方法只能解决attachEngine后又attachEngine的crash,运行后就会出现detachEngine后detachEngineIfNeed的crash点,就是个NPE,解决方法也简单,上面的
FlutterBoostPlatformViewsController
中已经做了保护,detachFromView
中加了空判定。0aydgbwb3#
为什么不能在FlutterBoostFragment里面的 didFragmentHide把 performDetach加回来?
dgsult0t4#
大概是,无法保证多个Fragment的情况下,可见Fragment的onResume方法和需要hide的fragment的didFragmentHide的方法的调用顺序把。
3pmvbmvn5#
确实有这方面的问题。不过如果是在一个FragmentTransaction 顺序 操作多个fragment 就没问题了