Flutter 与本机iOS异常不一致的颤振行为

Flutter 与本机iOS异常不一致的颤振行为,flutter,Flutter,在我的Flatter应用程序中,我设置了main()以捕获运行时错误,如下所示: void main() async { runZoned< Future<void> >(() async { runApp ( MyApp() ); }, onError: ( error, stackTrace ) async { print("Got an error"); // ... }); } 以下是And

在我的Flatter应用程序中,我设置了main()以捕获运行时错误,如下所示:

void main() async
{
    runZoned< Future<void> >(() async {
        runApp ( MyApp() );
    }, onError: ( error, stackTrace ) async {
        print("Got an error");
        // ...
    });
}
以下是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();
            }

        }
    });

}
- (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];
}
执行此代码时,IllegalStateException被“传播”到flift的main()函数中的onError:处理程序,我得到了一些信息和一点堆栈跟踪,正如预期的那样

以下是iOS实现:

@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();
            }

        }
    });

}
- (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];
}
在这种情况下,永远不会调用颤振的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<…>
与设备的连接中断。
***第一次抛出调用堆栈:
(
0 CoreFoundation 0x00000001065cf1bb例外预处理+331
1 libobjc.A.dylib 0x0000000105b6d735 objc_异常_抛出+48
2运行程序0x0000000103cd0772 _57-[AppDelegate应用程序:didFinishLaunchingWithOptions:][u block_invoke+226
3颤振0x0000000103d7b9a2 _45-[flatterMethodChannel setMethodCallHandler:][u block_invoke+115
4颤振0x0000000103d98616_ZNK5外壳21平台消息路由器21手持平台消息EN3FML6REFPTRIN5BLINK15平台消息EEE+166
5颤振0x0000000103d9bfbe\u ZN5外壳15平台视图IOS21手持平台消息EN3FML6REFPTRIN5BLINK15平台消息EEE+38
6颤振0x0000000103dec8e9_ZNSt3___110___功能6_功能5外壳5外壳29发动机手柄
这看起来有点像iosland的堆栈跟踪输出,但是没有任何东西像Android那样“传播”到fliftonError:处理程序

值得一提的是,这只会发生在本机NSException上,如果我使用类似于assert(false)的东西强制崩溃(在模拟器和物理设备上),也会发生这种情况,但如果我在iOS端使用[flutterror error withcode:…]而不是本机NSException,则不会发生这种情况


那么,有没有一种方法可以让本机iOS异常和崩溃传播回flatter中的onError:处理程序?

看看这篇文章,它解释了地下方法通道之间的一些主要差异。我认为iOS上的基本回调实现没有将异常映射到结果,因此,为了解决这一问题,您应该执行try-catch并将其映射到结果,正如在颤振文档中所做的那样:result(颤振错误(代码:“不可用”,消息:“电池信息不可用”,详细信息:nil))您是否尝试过使用“平台上异常…”捕获它,您需要导入“包:flatter/services.dart”。只是想知道这是否有帮助。问题跟踪。由OP打开。