Flutter 入門-本地訪問-MethodChannel

Dart4Flutter - 01 – 變量、類型和函數java

Dart4Flutter – 02 –控制流 和異常git

Dart4Flutter – 03 – 類和泛型github

Dart4Flutter – 04 – 異步和庫異步

Dart4Flutter - 拾遺01 - flutter-dart環境搭建async

Dart4Flutter - 不可變性ide

Flutter入門 - 狀態管理函數

Flutter 入門實例1post

Flutter 入門 - Container 屬性詳解ui

Flutter 入門-本地訪問-MethodChannelthis

Flutter 實例 - 加載更多的ListView

Flutter 實例 - 從本地到Flutter通訊 - Event Channels

Flutter 做爲一種跨平臺的解決方案,有訪問本地資源的能力。主要是經過Channel完成,你能夠稱之爲隧道。主要是MethodChannel和MessageChannel兩種,第一種是調用方法,第二種是傳遞信息。首先通訊的雙方是Flutter和本地操做系統或者應用,並且方法的調用和消息的方法能夠從任何一方發起,相似RPC(遠程過程調用)。

重點內容:

  • 主要是Flutter是一個比較獨立的環境,要想訪問本地的資源,Flutter提供了Channel機制,相似Cilent-Server模式或者RPC
  • 經過Channel的名稱打通Channel,隧道。
  • Flutter和本地是對稱的,請求能夠從任何一發發起,本教程主要是從Flutter給本地發送請求。

Flutter部分

若是你對Flutter的界面編寫部分不熟悉,能夠參考官方的文檔;

下面是UI部分的代碼

import 'package:flutter/material.dart';


void main() {
  runApp(new MaterialApp(
    home: new Scaffold(
      body: new PlatformTestBody(),
    ),
  ));
}

class PlatformTestBody extends StatefulWidget {
  @override
  PlatformTestBodyState createState() {
    return new PlatformTestBodyState();
  }
}

class PlatformTestBodyState extends State<PlatformTestBody> {

  String nativeMessage =''; 
  @override
  Widget build(BuildContext context) {
    return new Container(
      color: Colors.pinkAccent,
      child: new Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          new Padding(
            padding: const EdgeInsets.only(left: 18.0, top: 200.0),
            child: new Text(
              'Tap the button to change your life!',
              style: new TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w500,
                  fontSize: 23.0),
            ),
          ),
          new Padding(
            padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 102.0),
            child: new RaisedButton(
              child: new Text('Click Me'),
              onPressed: () => print(''),
            ),
          ),
          new Padding(
            padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 102.0),
            child: new Text(
              nativeMessage,
              style: new TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w500,
                  fontSize: 23.0),
            ),
          )
        ],
      ),
    );
  }
}
複製代碼

如今咱們介紹關於本地資源訪問的問題,首先咱們要引入service包和async包。

// Add these lines to the top of the file
import 'package:flutter/services.dart';
import 'dart:async';
複製代碼

有了service包,咱們就能夠配置Flutter,發送請求到本地。聲明一個static const變量platformMethodChannel ,賦值MethodChannel類型的對象。

class PlatformTestBodyState extends State<PlatformTestBody> {
  //Add this line 
  static const platformMethodChannel = const MethodChannel('com.test/test');

  String nativeMessage ='';  
  @override
  Widget build(BuildContext context) {
      ...
複製代碼

注意,咱們給MethodChannel一個名字com.test/test,這個名字和本地那邊的要同樣。

咱們建立了MethodChannel,咱們準備一個用來發送請求的函數。咱們建立一個叫doNativeSuff的異步函數

Future<Null> doNativeSuff() async {
 
  }
複製代碼

代替RaisedButton中的onPressed函數 print('')doNativeSuff()

child: new RaisedButton(
    child: new Text('Click Me'),
    onPressed: () => print(''),
),
複製代碼
child: new RaisedButton(
    child: new Text('Click Me'),
    onPressed: () => doNativeSuff(),
),
複製代碼

下面解釋整個doNativeSuff 方法

Future<Null> doNativeSuff() async {
    String _message; // 1
    try {
      final String result =
          await platformMethodChannel.invokeMethod('changeLife');// 2
      _message = result;
      print(result);
    } on PlatformException catch (e) {
      _message = "Sadly I can not change your life: ${e.message}.";
    }
    setState(() {
        nativeMessage = _message; // 3
    });
  }
複製代碼
  1. 聲明一個String變量_message,用於存須要顯示在界面上的信息,可能來自本地,也可能來自Flutter
  2. 發送請求,await platformMethodChannel.invokeMethod('changeLife') 是調用本地的changeLife 方法,而且這個方法是異步的,await表示阻塞執行。
  3. nativeMessage = _message; 表示通知Flutter狀態改變,刷新界面。

本地部分

本教程只關注Android方面的代碼。在Android studio 中打開MainActivity.java,在文件的最頂上添加一下代碼,是Flutter插件的相關依賴

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;
複製代碼

聲明CHANNEL 變量,和Flutter中MethodChannel的名字同樣com.test/test,建議直接從Flutter那邊複製粘貼。

public class MainActivity extends FlutterActivity {
  private static final String CHANNEL = "com.test/test"; 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    ...
複製代碼

使用上面的CHANNELFlutterView 建立一個MethodChannel

public class MainActivity extends FlutterActivity {
  private static final String CHANNEL = "com.test/test";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
    new MethodChannel(getFlutterView(), CHANNEL)// 重點
複製代碼

在MethodChannel的中調用.setMethodCallHandler() 方法,須要一個MethodCallHandler 對象,是一個匿名內部類,有一個方法onMethodCall,在Flutter發送請求事,onMethodCall方法會執行。

public class MainActivity extends FlutterActivity {
  private static final String CHANNEL = "com.test/test";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
    new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
      new MethodCallHandler() {
        @Override
        public void onMethodCall(MethodCall methodCall, Result result) {
        }
      }
    );
  }

}
複製代碼

onMethodCall方法中有兩個參數 MethodCall 和 result,MethodCall 中有關當前請求的信息,例如調用方法的名字changeLife;Result用於發送信息給Flutter。

在onMethodCall中判斷當前請求是否爲changeLife,若是是經過resultsuccess 返回信息:Life Changed .

public void onMethodCall(MethodCall methodCall, Result result) {
  if (methodCall.method.equals("changeLife")){
    String message ="Life Changed";
    result.success(message);
  }
  ...
複製代碼

這樣Flutter就能夠訪問,本地的方法了。

一般應用於訪問本地資源,例如訪問相機,本地存儲,圖片的選擇

本教程主要了解的是MethodChannel,還有MessageChannel沒有解析,下次再說。

參考

相關文章
相關標籤/搜索