Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@kangwang1988
Copy link
Contributor

When the engine is a embedder engine(not passed by developers), the shell is destroyed on disappearing. However, when FlutterVC present a NativeVC and go back, the shell needs to be created again. Otherwise, it will crash due to null shell assert.

@kangwang1988 kangwang1988 requested a review from dnfield January 18, 2019 10:31
@kangwang1988 kangwang1988 changed the title Fix https://github.com/flutter/flutter/issues/26660 Fix flutter/flutter#26660 Jan 18, 2019
@dnfield
Copy link
Contributor

dnfield commented Jan 18, 2019

I'm not sure this is the right fix - when I try it locally I don't get a crash anymore, but I also don't get back to the original viewcontroller....

@kangwang1988
Copy link
Contributor Author

@dnfield
I think your last refactor to break the recycle reference between FlutterViewController and FlutterEngine works.
However, if it destroy the shell while the FlutterViewController remains, every assert or reference to the shell will fail(for example, touchBegan: or in this case), it will crash. Once it destroy the shell, it needs to recreate it when necessary.

@dnfield
Copy link
Contributor

dnfield commented Jan 19, 2019

Something's broken, I agree. I'm trying to figure out how to fix this and not break the previous problem :)

@kangwang1988
Copy link
Contributor Author

kangwang1988 commented Jan 19, 2019

I'm not sure this is the right fix - when I try it locally I don't get a crash anymore, but I also don't get back to the original viewcontroller....

Are you saying https://github.com/KevinTheGray/flutterissues?
In flutterissues, it just present and will not go back.

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
  [GeneratedPluginRegistrant registerWithRegistry:self];
  FlutterMethodChannel* launchChannel = [FlutterMethodChannel
                                          methodChannelWithName:@"launch"
                                          binaryMessenger:controller];
  [launchChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
    [controller presentViewController:[[UIViewController alloc] init] animated:YES completion:nil];
  }];
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@kangwang1988
Copy link
Contributor Author

kangwang1988 commented Jan 19, 2019

See git@github.com:kangwang1988/flutterissues.git
Made it dismissable, however, I found another problem after FlutterVC present a native one and dismiss back.
Though the touch event can be passed from iOS to Flutter Side, the gesture detection will fail.

2019-01-19 11:55:41.731621+0800 Runner[4302:824042] flutter: KWLM:main.dart:main called!
2019-01-19 11:55:41.732276+0800 Runner[4302:824042] flutter: KWLM:main.dart:MyApp.build called!
2019-01-19 11:55:49.346673+0800 Runner[4302:824042] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:49.366707+0800 Runner[4302:824042] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:49.375902+0800 Runner[4302:824042] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:49.392570+0800 Runner[4302:824042] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:49.408176+0800 Runner[4302:824042] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:49.408365+0800 Runner[4302:824042] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:49.409053+0800 Runner[4302:824042] flutter: KWLM:main.dart:_MyHomePageState.build.onTap called!
2019-01-19 11:55:50.218721+0800 Runner[4302:824121] flutter: KWLM:main.dart:main called!
2019-01-19 11:55:50.219643+0800 Runner[4302:824121] flutter: KWLM:main.dart:MyApp.build called!
2019-01-19 11:55:52.746989+0800 Runner[4302:824121] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:52.778007+0800 Runner[4302:824121] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:52.794216+0800 Runner[4302:824121] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:52.810991+0800 Runner[4302:824121] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:52.827744+0800 Runner[4302:824121] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand called!
2019-01-19 11:55:52.835336+0800 Runner[4302:824121] flutter: KWLM:gestures:converter.dart:PointerEventConverter.expand call

But I do think this is another problem.

@dnfield
Copy link
Contributor

dnfield commented Jan 19, 2019

Ahh I missed something in there.

I had a really hectic day today, but I'll take a closer look at this soon - sorry for the delay.

@kangwang1988
Copy link
Contributor Author

Ahh I missed something in there.

I had a really hectic day today, but I'll take a closer look at this soon - sorry for the delay.

Never mind.
Take care.


if (_engineNeedsLaunch) {
if (_isEmbedEngine) {
[_engine.get() createShell:nil libraryURI:nil];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure this will lead to unexpected loss of state. If we allow the engine to get torn down here, restarting it will prevent th ecrash but also restart the app from scratch.

Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate this PR - it helped me understand the problem better for sure. However, I think to really get at this we should override the present methods on FlutterViewController to make sur ethe engine doesn't disappear in those scenarios. What do you think?

@kangwang1988
Copy link
Contributor Author

kangwang1988 commented Jan 22, 2019

@dnfield
I though it would make things more complicated if you want to detect if the engine should remain based on the viewDidDisappear logic. There are several cases which might cause the viewDidDisappear logic, right?
push, present, setViewControllers directly, added as a childViewController, etc.

Besides, I don't think it's a good idea to process the logic depending on the viewDidDisappear one, it would be weird as the state is lost, as you mentioned in my patch.

dealloc seems a better function to do this.
However ,there is a recycle retain.

Can we add an external api exposed to developers so that we can still break the recycle retain, and don't call it from the default intra logic?

@dnfield
Copy link
Contributor

dnfield commented Jan 22, 2019

Can you take a look at #7544? I agree with you that overriding those methods is probably not the way to go - this is a little bit different.

@kangwang1988
Copy link
Contributor Author

@dnfield
OK

@kangwang1988
Copy link
Contributor Author

Close #26660 via #7544

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants