Flutter行为与本地iOS异常不一致

时间:2018-12-24 23:34:03

标签: flutter

在Flutter应用中,我设置了 main()来捕获运行时错误,如下所示:

void main() async
{
    runZoned< Future<void> >(() async {
        runApp ( MyApp() );
    }, onError: ( error, stackTrace ) async {
        print("Got an error");
        // ...
    });
}

这对于所有Flutter级错误都适用,对于在Android上本地运行的代码也适用,但是对于iOS应用程序从未调用 onError:处理程序。

一个例子:

我的Flutter应用通过方法通道调用以下本机方法:

void _onButtonClick() async {
    final channel = const MethodChannel('my-custom-channel');
    await channel.invokeMethod('testMethod');
}

这是Android实现:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);

    MethodChannel channel = new MethodChannel(getFlutterView(), "my-custom-channel");

    channel.setMethodCallHandler(new MethodCallHandler() {
        @Override
        public void onMethodCall(MethodCall call, Result result) {

            if ( call.method.equals("testMethod") ) {
                throw new IllegalStateException("This is a native Android exception.");
            } else {
                result.notImplemented();
            }

        }
    });

}

执行此代码时, IllegalStateException 被“传播”回Flutter的 main()函数中的 onError:处理程序,并且正如预期的那样,我得到了一些信息和一些堆栈跟踪。

这是iOS实现:

- (BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;

    FlutterMethodChannel* channel = [FlutterMethodChannel
        methodChannelWithName:@"my-custom-channel"
        binaryMessenger:controller];

    [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {

        if ( [call.method isEqualToString:@"testMethod"] )
        {
            @throw([NSException
                exceptionWithName:@"iOS Exception"
                reason:@"Testing native iOS exceptions"
                userInfo:nil]);

            result(FlutterMethodNotImplemented);
        }
        else
        {
            result(FlutterMethodNotImplemented);
        }

    }];

    [GeneratedPluginRegistrant registerWithRegistry:self];
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

在这种情况下,永远不会调用Flutter main()函数中的 onError:处理程序。控制台输出如下:

Lost connection to device.
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001065cf1bb __exceptionPreprocess + 331
    1   libobjc.A.dylib                     0x0000000105b6d735 objc_exception_throw + 48
    2   Runner                              0x0000000103cd0772 __57-[AppDelegate application:didFinishLaunchingWithOptions:]_block_invoke + 226
    3   Flutter                             0x0000000103d7b9a2 __45-[FlutterMethodChannel setMethodCallHandler:]_block_invoke + 115
    4   Flutter                             0x0000000103d98616 _ZNK5shell21PlatformMessageRouter21HandlePlatformMessageEN3fml6RefPtrIN5blink15PlatformMessageEEE + 166
    5   Flutter                             0x0000000103d9bfbe _ZN5shell15PlatformViewIOS21HandlePlatformMessageEN3fml6RefPtrIN5blink15PlatformMessageEEE + 38
    6   Flutter                             0x0000000103dec8e9 _ZNSt3__110__function6__funcIZN5shell5Shell29OnEngineHandle<…>

这看起来有点像iOS平台上的堆栈跟踪输出,但没有任何东西像Android上那样“传播”到Flutter onError:处理程序。

值得一提的是,这仅在本机NSExceptions中发生,并且如果我在模拟器和物理设备上都使用 assert(false)之类的方法强制崩溃时,也会发生这种情况,但是确实如此如果我使用 [FlutterError errorWithCode:...] 而不是iOS端的本机NSException,则不会发生。

因此,有没有办法让本地iOS异常和崩溃传播回Flutter中的 onError:处理程序?

0 个答案:

没有答案