Sumérjase profundamente en el mundo nativo usando canales de método: la aplicación no responde

Foto de Joseph Barrientos y Unsplash

Introducción

Flutter incluye una forma integrada de comunicarse con la plataforma subyacente: el llamado canales de método. Pero… espera un minuto… Flutter no es un Marco multiplataforma? ¿Por qué, entonces, deberíamos descender al mundo «nativo»? Bueno, a veces queremos usar una determinada función de HW como la cámara o la geolocalización y no podemos encontrar ningún complemento o biblioteca de terceros que se adapte a nuestras necesidades. Luego tenemos que hacer todo el trabajo nosotros mismos y acceder a la función de forma nativa usando canales de método.

visión general

Los canales de método son solo otro tipo de objetos expuestos por la API de Flutter. Cada canal se identifica por su Apellidopor lo que cualquier “puente” de comunicación entre Flutter y la plataforma nativa debe tener uno identificador único. Debido a esto, generalmente configuramos nombres combinando el identificador del paquete y un sufijo, por ejemplo: static const String PACKAGE = «com.bgomez.flutter_weather»; Constante estática String SUFFIX = «/openweather»;

el intercambio de datos

Los canales de método se pueden ver como un flujo de datos directo con el sistema operativo nativo, que nos permite llamar a métodos y enviar o recuperar información. Todos los datos intercambiados a través de canales de métodos se envían como Mensajes: un mensaje es solo un paquete con algunos pares clave-valor que la plataforma serializa y deserializa automáticamente. Todos los mensajes intercambiados se envían de forma asíncrona.

arquitectura del sistema

Arquitectura de canal de método de Flutter Cuando se usan canales de método, el marco de trabajo de Flutter y la plataforma subyacente siguen un servidor de clientes arquitectura. El escenario más común es cuando:

  • en el lado de Flutter solicitamos recursos (por lo que Flutter actúa como un cliente)
  • En el lado nativo, realizamos las operaciones necesarias y entregamos el resultado (para que el lado nativo actúe como servidor).

Sin embargo, también podemos configurar el canal para intercambiar los roles de cada lado.

configuración del proyecto

Además de los archivos dart en nuestra aplicación, debemos agregar cuando usamos canales de método Código nativo de Android y/o ios así como cada uno en su carpeta respectiva.

flujo de trabajo

  1. En el lado nativo para implementar el código requerido
  2. En el lado nativo Configurar el «punto de entrada» nativo clase
  3. En el lado de Flutter Crear un canal de método
  4. En la página de Flutter, usa el objeto anterior Llame a la operación nativa

Los pasos necesarios para que un canal de método funcione son los mismos para Android e iOS, pero los detalles de implementación cambian en el lado nativo. Las siguientes secciones toman la implementación nativa de Android como ejemplo e implementan un canal de método para recuperar datos sobre el pronóstico del tiempo.

1. Lado nativo: implementación

Primero, definamos una clase llamada «OpenWeatherService» que es responsable de obtener el pronóstico del tiempo desde un servidor remoto. La implementación de la clase utiliza corrutinas de Kotlin: object OpenWeatherService { val URL = «api.openweathermap.org» suspend fun getForecast( appId: String, lat: Double, lon: Double) : String { … //XXX: acceda a alguna API y Obtener datos meteorológicos… }

2. Lado nativo: configurar el punto de entrada

Después de eso, «engancharemos» la clase de servicio anterior para que se pueda acceder a sus métodos desde la aplicación nativa de Android. Para esto tenemos que:

  • registrar el nombre de las operaciones a las que queremos acceder
  • atajo cada uno de estos nombres al correspondiente ejecución operativa dentro de la clase

En Flutter, el punto de entrada para el proyecto de Android subyacente es el método MainActivity.configureFlutterEngine(). Por lo tanto, tanto el registro como la vinculación deben realizarse con este método: valor privado CANAL = «com.bgomez.flutter_weather» valor privado SUFIJO = «/openweather» valor privado GET_CURRENT = «getCurrentWeather» valor privado GET_FORECAST = «getForecast» override fun configureFlutterEngine( @NonNull flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel( binaryMessenger, «$CHANNEL$SUFFIX») .setMethodCallHandler { llamada, resultado -> // CLIMA ACTUAL if (llamada.método == GET_CURRENT) { val res = OpenWeatherService .getCurrentWeather(appId, lat, lon) result.success(res) // 24H FORECAST } else if (call.method == GET_FORECAST) { val res= OpenWeatherService .getForecast(appId, lat, lon) resultado.success (res) } } } La llamada al canal del método debe realizarse en el Subproceso de interfaz de usuario de Androidpor lo tanto, debemos envolver el fragmento anterior con algún código de manejo de subprocesos: anular fun configureFlutterEngine( @NonNull flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) // llamar al subproceso de interfaz de usuario android.os.Handler( android.os .Looper. getMainLooper()).post { //XXX: el código de canal del método anterior va aquí }) }

3. Flutter page: crea un canal de método

Como se mencionó anteriormente, el marco Flutter incluye el tipo de datos MethodChannel. Las instancias de esta clase representan un puente de comunicación entre Flutter y Native: un canal es creado directamente por Llamando al constructor de la clase y pasar su nombre como parámetro. Podemos envolver la operación en un método de fábrica: static const String PACKAGE =»…»; Constante estática String SUFFIX = «/weather»; MethodChannel create() { return MethodChannel(«$PAQUETE$SUFIJO»); } Después de eso usamos la función anterior para crear nuestra instancia: final channel = create();

4. Flutter side: llama al método nativo usando MethodChannel

Por último, pero no menos importante, debemos invocar operaciones en la plataforma subyacente utilizando MethodChannel.invokeMethod() tomados como parámetros:

  • la Nombre del método nativo queremos ejecutar
  • la mensaje Queremos pasar al lado nativo. Este es solo un objeto JSON que contiene pares clave-valor con los valores necesarios para realizar la operación

final json = esperar canal .invokeMethod( «getForecast», { «lat»: settings.city.geo.lat, «lon»: settings.city.geo.lon, «appId»: settings.appId }); ¡Y eso es todo! Nuestro canal de método ahora está listo para comunicarse con la plataforma subyacente.

Código de muestra

Como de costumbre, consulte este repositorio para Código fuente. ¡Escríbeme la próxima vez! https://github.com/begomez/FlutterForecast

Referencias:

https://flutter.dev/docs/development/platform-integration/platform-channels

Como esto:

Me gusta Cargando…

Relacionado

Deja una respuesta

Tu dirección de correo electrónico no será publicada.