Flutter - pisanie kodu specyficznego dla Androida

Flutter zapewnia ogólną strukturę dostępu do funkcji specyficznych dla platformy. Umożliwia to deweloperowi rozszerzenie funkcjonalności frameworka Flutter przy użyciu kodu specyficznego dla platformy. Funkcje specyficzne dla platformy, takie jak aparat, poziom naładowania baterii, przeglądarka itp., Są łatwo dostępne za pośrednictwem frameworka.

Ogólną ideą dostępu do kodu specyficznego dla platformy jest prosty protokół przesyłania wiadomości. Kod Flutter, klient i kod platformy oraz host są powiązane ze wspólnym kanałem wiadomości. Klient wysyła wiadomość do hosta za pośrednictwem kanału wiadomości. Host nasłuchuje na kanale wiadomości, odbiera wiadomość i wykonuje niezbędne funkcje, a na koniec zwraca wynik do klienta za pośrednictwem kanału wiadomości.

Architektura kodu specyficzna dla platformy jest pokazana na schemacie blokowym podanym poniżej -

Protokół przesyłania wiadomości używa standardowego kodeka wiadomości (klasa StandardMessageCodec), który obsługuje serializację binarną wartości podobnych do JSON, takich jak liczby, ciągi znaków, wartości logiczne itp. Serializacja i deserializacja działa w sposób przejrzysty między klientem a hostem.

Napiszmy prostą aplikację do otwierania przeglądarki za pomocą Android SDK i zrozummy, jak to zrobić

  • Utwórz nową aplikację Flutter w Android Studio, flutter_browser_app

  • Zastąp kod main.dart poniższym kodem -

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp()); 
class MyApp extends StatelessWidget { 
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(title: 'Flutter Demo Home Page'),
      );
   }
}
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(
            title: Text(this.title), 
         ), 
         body: Center(
            child: RaisedButton( 
               child: Text('Open Browser'), 
               onPressed: null, 
            ), 
         ), 
      ); 
   }
}
  • Tutaj utworzyliśmy nowy przycisk do otwierania przeglądarki i ustawiania jej metody onPressed na null.

  • Teraz zaimportuj następujące pakiety -

import 'dart:async'; 
import 'package:flutter/services.dart';
  • W tym przypadku services.dart zawierają funkcję wywoływania kodu specyficznego dla platformy.

  • Utwórz nowy kanał wiadomości w widżecie MyHomePage.

static const platform = const 
MethodChannel('flutterapp.tutorialspoint.com/browser');
  • Napisz metodę _openBrowser, aby wywołać metodę specyficzną dla platformy, metodę openBrowser za pośrednictwem kanału komunikatów.

Future<void> _openBrowser() async { 
   try {
      final int result = await platform.invokeMethod(
         'openBrowser', <String, String>{ 
            'url': "https://flutter.dev" 
         }
      ); 
   } 
   on PlatformException catch (e) { 
      // Unable to open the browser 
      print(e); 
   }
}

Tutaj użyliśmy platform.invokeMethod do wywołania openBrowser (wyjaśnione w kolejnych krokach). openBrowser ma argument, url, aby otworzyć określony adres URL.

  • Zmień wartość właściwości onPressedButton RaisedButton z null na _openBrowser.

onPressed: _openBrowser,
  • Otwórz plik MainActivity.java (w folderze Androida) i zaimportuj wymaganą bibliotekę -

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 

import io.flutter.app.FlutterActivity; 
import io.flutter.plugin.common.MethodCall; 
import io.flutter.plugin.common.MethodChannel; 
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 
import io.flutter.plugin.common.MethodChannel.Result; 
import io.flutter.plugins.GeneratedPluginRegistrant;
  • Napisz metodę, otwórz przeglądarkę, aby otworzyć przeglądarkę

private void openBrowser(MethodCall call, Result result, String url) { 
   Activity activity = this; 
   if (activity == null) { 
      result.error("ACTIVITY_NOT_AVAILABLE", 
      "Browser cannot be opened without foreground 
      activity", null); 
      return; 
   } 
   Intent intent = new Intent(Intent.ACTION_VIEW); 
   intent.setData(Uri.parse(url)); 
   
   activity.startActivity(intent); 
   result.success((Object) true); 
}
  • Teraz ustaw nazwę kanału w klasie MainActivity -

private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser";
  • Napisz specyficzny dla Androida kod, aby ustawić obsługę wiadomości w metodzie onCreate -

new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler( 
   new MethodCallHandler() { 
   @Override 
   public void onMethodCall(MethodCall call, Result result) { 
      String url = call.argument("url"); 
      if (call.method.equals("openBrowser")) {
         openBrowser(call, result, url); 
      } else { 
         result.notImplemented(); 
      } 
   } 
});

Tutaj utworzyliśmy kanał wiadomości przy użyciu klasy MethodChannel i użyliśmy klasy MethodCallHandler do obsługi wiadomości. onMethodCall jest właściwą metodą odpowiedzialną za wywołanie prawidłowego kodu specyficznego dla platformy poprzez sprawdzenie wiadomości. Metoda onMethodCall wyodrębnia adres URL z wiadomości, a następnie wywołuje openBrowser tylko wtedy, gdy wywołanie metody to openBrowser. W przeciwnym razie zwraca metodę notImplemented.

Pełny kod źródłowy aplikacji jest następujący -

main.dart

MainActivity.java

package com.tutorialspoint.flutterapp.flutter_browser_app; 

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 
import io.flutter.app.FlutterActivity; 
import io.flutter.plugin.common.MethodCall; 
import io.flutter.plugin.common.MethodChannel.Result; 
import io.flutter.plugins.GeneratedPluginRegistrant; 

public class MainActivity extends FlutterActivity { 
   private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser"; 
   @Override 
   protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      GeneratedPluginRegistrant.registerWith(this); 
      new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
         new MethodCallHandler() {
            @Override 
            public void onMethodCall(MethodCall call, Result result) {
               String url = call.argument("url"); 
               if (call.method.equals("openBrowser")) { 
                  openBrowser(call, result, url); 
               } else { 
                  result.notImplemented(); 
               }
            }
         }
      ); 
   }
   private void openBrowser(MethodCall call, Result result, String url) {
      Activity activity = this; if (activity == null) {
         result.error(
            "ACTIVITY_NOT_AVAILABLE", "Browser cannot be opened without foreground activity", null
         ); 
         return; 
      } 
      Intent intent = new Intent(Intent.ACTION_VIEW); 
      intent.setData(Uri.parse(url)); 
      activity.startActivity(intent); 
      result.success((Object) true); 
   }
}

main.dart

import 'package:flutter/material.dart'; 
import 'dart:async'; 
import 'package:flutter/services.dart'; 

void main() => runApp(MyApp()); 
class MyApp extends StatelessWidget {
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(
            title: 'Flutter Demo Home Page'
         ), 
      ); 
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   static const platform = const MethodChannel('flutterapp.tutorialspoint.com/browser'); 
   Future<void> _openBrowser() async {
      try {
         final int result = await platform.invokeMethod('openBrowser', <String, String>{ 
            'url': "https://flutter.dev" 
         });
      }
      on PlatformException catch (e) { 
         // Unable to open the browser print(e); 
      } 
   }
   @override 
   Widget build(BuildContext context) {
      return Scaffold( 
         appBar: AppBar( 
            title: Text(this.title), 
         ), 
         body: Center(
            child: RaisedButton( 
               child: Text('Open Browser'), 
               onPressed: _openBrowser, 
            ), 
         ),
      );
   }
}

Uruchom aplikację i kliknij przycisk Otwórz przeglądarkę, a zobaczysz, że przeglądarka jest uruchomiona. Aplikacja Browser - Strona główna jest pokazana na zrzucie ekranu tutaj -