Пример #1
0
        private void HandleMethodCall(FlutterMethodCall call, FlutterResult callback)
        {
            // Return an error if Flutter is invoking method calls through method channel
            // when bridge is configured for WebSocket communication
            if (Mode == FlutnetBridgeMode.WebSocket)
            {
                callback(ConstantsEx.FlutterMethodNotImplemented);
                return;
            }

            // Extract target method information from MethodCall.Method
            FlutnetMethodInfo methodInfo;
            NSObject          dartReturnValue;

            try
            {
                methodInfo      = JsonConvert.DeserializeObject <FlutnetMethodInfo>(call.Method, FlutterInterop.JsonSerializerSettings);
                dartReturnValue = FlutterInterop.ToMethodChannelResult(0);
            }
            catch (Exception ex)
            {
                callback(FlutterError.Create(FlutnetErrorCode.OperationNotImplemented.ToString(), ex.Message, null));
                return;
            }

            // Send an empty - successful - response to immediately free Flutter thread
            callback(dartReturnValue);

            nint[] taskId = new nint[1];

            taskId[0] = UIApplication.SharedApplication.BeginBackgroundTask(() =>
            {
                FlutnetException error = new FlutnetException(FlutnetErrorCode.OperationCanceled);
                MainThread.BeginInvokeOnMainThread(() => SendError(methodInfo, error));
                UIApplication.SharedApplication.EndBackgroundTask(taskId[0]);
            });

            // Run the call in Background
            Task.Run(() =>
            {
                BackgroundHandleMethodCall(methodInfo, call);
                UIApplication.SharedApplication.EndBackgroundTask(taskId[0]);
            });
        }
Пример #2
0
        /// <summary>
        /// Invoke a platform operation with the specified arguments.
        /// </summary>
        public static PlatformOperationResult Run(FlutnetRuntime.OperationInfo operation, object[] arguments)
        {
            // Check if the operation must be invoked on the main (UI) thread
            bool mainThreadRequired = false;

#if __ANDROID__
            mainThreadRequired = operation.OperationAttribute.AndroidMainThreadRequired;
#elif __IOS__
            mainThreadRequired = operation.OperationAttribute.IosMainThreadRequired;
#endif

            object    operationResult = null;
            Exception operationError  = null;

            // 1. Async call on UI Thread
            if (mainThreadRequired && operation.IsAsyncTask)
            {
                ManualResetEvent uiFinishEvent = new ManualResetEvent(false);
                MainThread.BeginInvokeOnMainThread(() =>
                {
                    Task task = (Task)operation.DelegateWithResult.Invoke(arguments);
                    task.ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            operationError = t.Exception?.GetBaseException();
                        }
                        else if (t.IsCanceled)
                        {
                            operationError = new FlutnetException(FlutnetErrorCode.OperationCanceled);
                        }
                        else
                        {
                            operationResult = t.TaskResult();
                        }
                        uiFinishEvent.Set();
                    });
                });
                uiFinishEvent.WaitOne();
            }
            // 2. Sync call on UI Thread
            else if (mainThreadRequired)
            {
                ManualResetEvent uiFinishEvent = new ManualResetEvent(false);
                MainThread.BeginInvokeOnMainThread(() =>
                {
                    try
                    {
                        if (operation.HasResult)
                        {
                            operationResult = operation.DelegateWithResult.Invoke(arguments);
                        }
                        else
                        {
                            operation.Delegate.Invoke(arguments);
                            operationResult = null;
                        }
                    }
                    catch (Exception ex)
                    {
                        operationError = ex;
                    }
                    finally
                    {
                        uiFinishEvent.Set();
                    }
                });
                uiFinishEvent.WaitOne();
            }
            // 3. Async call on Background Thread
            else if (operation.IsAsyncTask)
            {
                ManualResetEvent taskFinishEvent = new ManualResetEvent(false);
                Task             task            = (Task)operation.DelegateWithResult.Invoke(arguments);
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        operationError = t.Exception?.GetBaseException();
                    }
                    else if (t.IsCanceled)
                    {
                        operationError = new FlutnetException(FlutnetErrorCode.OperationCanceled);
                    }
                    else
                    {
                        operationResult = t.TaskResult();
                    }
                    taskFinishEvent.Set();
                });
                taskFinishEvent.WaitOne();
            }
            // 4. Sync call on Background Thread
            else
            {
                try
                {
                    if (operation.HasResult)
                    {
                        operationResult = operation.DelegateWithResult.Invoke(arguments);
                    }
                    else
                    {
                        operation.Delegate.Invoke(arguments);
                        operationResult = null;
                    }
                }
                catch (Exception ex)
                {
                    operationError = ex;
                }
            }

            // Return the result
            return(new PlatformOperationResult
            {
                Result = operationResult,
                Error = operationError
            });
        }