flutter項目 通道Channel封裝及使用案例


flutter 與原生通道封裝

channel_tools.dart文件

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

/*
 * 參考文檔
 * 官網 https://flutter.cn/docs/development/platform-integration/platform-channels
 * Flutter與Native數據交互,MethodChannel https://www.jianshu.com/p/f2755c301a3e
 * Dart語法 http://dart.goodev.org/guides/language/language-tour
 * 雙向通訊:https://blog.csdn.net/zl18603543572/article/details/96043692
 */
/*
 * 通道的客戶端和宿主端通過傳遞給通道構造函數的通道名稱進行連接
 * 一個應用中所使用的所有通道名稱必須是唯一的
 * 使用唯一的域前綴為通道名稱添加前綴,比如:samples.flutter.dev/battery
 */
/*
 * Flutter 與 Android iOS 原生的通信有以下三種方式
 * BasicMessageChannel 實現 Flutter 與 原生(Android 、iOS)雙向通信
 * MethodChannel 實現 Flutter 與 原生原生(Android 、iOS)雙向通信
 * EventChannel 實現 原生原生(Android 、iOS)向Flutter 發送消息 僅支持數據單向傳遞,無返回值。
 */
//構建通道 (唯一) xxxxxx 自定義通道標識

//BasicMessageChannel
const basicMessageChannel = const BasicMessageChannel(
    'xxxxxx', StandardMessageCodec());

//MethodChannel
const methodChannel = const MethodChannel('xxxxxx');

//EventChannel
const eventChannel = const EventChannel('xxxxxx');
/*
 * BasicMessageChannel
 * 實現Flutter 調用Android iOS原生方法並回調
 * arguments 發送給原生的參數 ,自定義基本數據格式{"method": "test", "content": "flutter 中的數據", "code": 100}
 * return數據 原生發給Flutter的參數,自定義基本數據格式{"code":100,"message":"消息","content":內容}
 */
Future<Map> toolsBasicChannelMethodWithParams(Map arguments) async {
  var result;
  try {
    result = await basicMessageChannel.send(arguments);
  } catch (e) {
    result = {'Failed': e.message};
  }
  return result;
}

/*
 * MethodChannel
 * 在方法通道上調用方法invokeMethod
 * methodName 方法名稱
 * params 發送給原生的參數,自定義基本數據格式{"code":100,"message":"消息","content":內容}
 * return數據 原生發給Flutter的參數,自定義基本數據格式{"code":100,"message":"消息","content":內容}
 */
Future<Map> toolsMethodChannelMethodWithParams(String methodName,
    [Map params]) async {
  var res;
  try {
    res = await methodChannel.invokeMethod('$methodName', params);
  } catch (e) {
    res = {'Failed': e.message};
  }
  return res;
}

/*
 * EventChannel
 * return數據 原生發給Flutter的參數,自定義基本數據格式{"code":100,"message":"消息","content":內容}
 * result listen監聽結果
 */
toolsEventChannelMethod(Function result) {
  //不指定返回值類型,函數返回值默認為Object
  eventChannel.receiveBroadcastStream().listen(result);
}

案例文件

import 'package:flutter/material.dart';
//導入ChannelTools文件
import 'package:flutter/services.dart';
import 'package:flutter_action/Channel/channel_tools.dart';
/*
* 參考文檔
* https://flutter.cn/docs/development/platform-integration/platform-channels
* https://www.jianshu.com/p/74c9e389e73f
* https://blog.csdn.net/mcy456/article/details/96774539
*
* */
class ChannelUseCasesRoute extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text("MethodChannel使用案例"),
        actions: <Widget>[
        ],
      ),
      body: ColumnWidget(
      ),
    );
  }
}
class ColumnWidget extends StatefulWidget {

  @override
  _ColumnWidgetState createState() => _ColumnWidgetState();
}
class _ColumnWidgetState extends State<ColumnWidget> {

  String  _result = "顯示接收接據";
  //BasicMessageChannel 調用原生方法並回調 按鈕點擊觸發事件
  void basicChannelMethod(){
    Map params = {"method":"test","context":"testValue","code": 200};
    toolsBasicChannelMethodWithParams(params).then((result){
      //result 原生回調結果
      _result = result.toString();
      print(result);
    });
    setState(() {

    });
  }
  //MethodChannel 調用原生方法並回調 按鈕點擊觸發事件
  void methodChannelMethod() {
    //調用ChannelTools中的方法 參數一方法名 參數二、Map類型鍵值對參數
    toolsMethodChannelMethodWithParams('methodChannelTest').then((result){
      //result 原生回調結果
      _result = result.toString();
    });
    setState(() {

    });
  }
 static const eventChannel = const EventChannel('semf.datacvg.com/eventChannel');

  //EventChannel 原生數據傳遞 按鈕點擊觸發事件
  void eventChannelMethod(){
    //data 原生
    toolsEventChannelMethod((data){
       _result = data;
    });
    setState(() {

    });
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
      child: Column(
        mainAxisAlignment:MainAxisAlignment.center,
        children: <Widget>[
          RaisedButton.icon(
              icon: Icon(Icons.send),
              onPressed: basicChannelMethod,
              label: Text('BasicMessageChannel 調用原生方法並回調')
          ),
          RaisedButton.icon(
              icon: Icon(Icons.send),
              onPressed: methodChannelMethod,
              label: Text('MethodChannel 調用原生方法並回調')
          ),
          RaisedButton.icon(
              icon: Icon(Icons.send),
              onPressed: eventChannelMethod,
              label: Text('EventChannel 調用原生方法並回調')

          ),
          SizedBox(
            width: 300,
            child: Container(
              child: Text('flutter接收數據'+_result),
            ),
          ),
        ],
      ),

    );
  }
}


//Toast.show("鑒權失敗!", context, duration: Toast.LENGTH_LONG, gravity: Toast.CENTER);

/*
    iOS  BasicMessageChannel原生實現方法
   _basicMethodChannel = [FlutterBasicMessageChannel messageChannelWithName:@"semf.datacvg.com/Test" binaryMessenger:[flutter binaryMessenger]];
    // 注冊方法等待flutter頁面調用
    [_basicMethodChannel setMessageHandler:^(id  _Nullable message, FlutterReply  _Nonnull callback) {
        NSString *method=message[@"method"];
        if ([method isEqualToString:@"test"]) {
            //調用原生自定義方法
            //[weakSelf testMethod];

            //返回flutter數據
            NSMutableDictionary *dic = [NSMutableDictionary dictionary];
            [dic setObject:@"basicMethodChannel 原生返回flutter的數據" forKey:@"message"];
            [dic setObject: [NSNumber numberWithInt:200] forKey:@"code"];
            [dic setObject: @"內容" forKey:@"context"];
            callback(dic);
        }
    }];
    ---------------
    iOS MethodChannel原生實現方法
     _methodChannel = [FlutterMethodChannel methodChannelWithName:@"semf.datacvg.com/semf" binaryMessenger:[flutter binaryMessenger]];

    [_methodChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
        NSLog(@"%@", call.method);
        NSLog(@"%@", call.arguments);
        if ([call.method isEqualToString:@"methodChannelTest"]) {
            //[weakSelf testMethod];

            //返回flutter數據
            NSMutableDictionary *dic = [NSMutableDictionary dictionary];
            [dic setObject:@"methodChannel 原生返回flutter的數據" forKey:@"message"];
            [dic setObject: [NSNumber numberWithInt:200] forKey:@"code"];
            [dic setObject: @"內容" forKey:@"context"];
            result(dic);
        }

    }];
    ----------------
    iOS EventChannel 原生實現方法
   <FlutterStreamHandler>
   FlutterEventChannel* eventChannle = [FlutterEventChannel eventChannelWithName:@"semf.datacvg.com/eventChannel" binaryMessenger:[flutter binaryMessenger]];
   [eventChannle setStreamHandler:self];

   數據代理 FlutterStreamHandler

  - (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments
                                       eventSink:(FlutterEventSink)events {}//此處的arguments可以轉化為剛才receiveBroadcastStream("init")的名稱,這樣我們就可以一個event來監聽多個方法實例
  - (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {}

 */

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM