Flutter和Native 通信 android端

通信用到的类

  1. MethodChannel
  2. EventChannel
  3. BasicMessageChannel

MethodChannel使用方式(flutter 调用原生方法)

1. 原生代码
  1. 定义通信标识
   private val METHOD_CHANNEL = "tip.flutter.io/method"
  1. 创建对象
 MethodChannel((getView() as FlutterView), METHOD_CHANNEL).setMethodCallHandler { call, result ->
           if (call.method == "getBatteryLevel") {
               val ba = getBatteryLevel()
               if (ba != -1) {
                   result.success(ba)
               } else {
                   result.error("UNAVAILABLE", "Battery level not available.", null)
               }
           } else {
               result.notImplemented()
           }
       }
  1. 定义原生方法
	private fun getBatteryLevel(): Int {
        return 123
    }
2. dart代码
  1. 创建对象
  static const platfrom = const MethodChannel("tip.flutter.io/method");
  1. 初始化方法
 Future<Null> _getBatteryLevel() async {
    String batteryLevel;
    try {
      final int result = await platfrom.invokeMethod("getBatteryLevel");
      batteryLevel = 'Battery level at $result % .';
    } on PlatformException catch (e) {
      batteryLevel = "Failed to get battery level: '${e.message}'.";
    }
    setState(() {
      _batteryLevel = batteryLevel;
    });
  }
  1. 调用方法
 @override
  void initState() {
    // TODO: implement initState
    _getBatteryLevel();
    super.initState();
  }

EventChannel使用方式(主要是native向flutter主动推送数据,例如推送电量,网络状态)

BasicMessageChannel使用方式(native->flutter,flutter->native)

完整nativie 代码如下

package com.gctech.nativeandflutter

import android.os.Bundle
import android.os.Handler
import android.view.View
import android.widget.Toast
import io.flutter.facade.FlutterFragment
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.StringCodec
import io.flutter.view.FlutterView
import java.util.*

/**
 *    author: yu.jl
 *    e-mail: [email protected]
 *    time  : 2019/7/24
 *    desc  :
 */
class FlutterBaseFragment : FlutterFragment() {
    private val METHOD_CHANNEL = "tip.flutter.io/method"
    private val EVENT_CHANNEL = "tip.flutter.io/event"
    private val MESSAGE_CHANNEL = "tip.flutter.io/message"
    private val handler = Handler()
    var mesageChan: BasicMessageChannel<String>? = null

    companion object {
        fun newInstance(router: String) = FlutterBaseFragment().apply {
            arguments = Bundle().apply {
                putString("router", router)
            }

        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        MethodChannel((getView() as FlutterView), METHOD_CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getBatteryLevel") {
                val ba = getBatteryLevel()
                if (ba != -1) {
                    result.success(ba)
                } else {
                    result.error("UNAVAILABLE", "Battery level not available.", null)
                }
            } else {
                result.notImplemented()
            }
        }
        EventChannel((getView() as FlutterView), EVENT_CHANNEL).setStreamHandler(object : EventChannel.StreamHandler {
            override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
                Timer().schedule(object : TimerTask() {
                    override fun run() {
                        handler.post {
                            events?.success("当前时间毫秒${System.currentTimeMillis()}")
                        }
                    }
                }, 1000, 1000)
            }

            override fun onCancel(p0: Any?) {
            }

        })
        mesageChan = BasicMessageChannel<String>(
            (getView() as FlutterView),
            MESSAGE_CHANNEL,
            StringCodec.INSTANCE
        )
        mesageChan?.setMessageHandler { a, b ->
            b.reply("aaaa${System.currentTimeMillis()}")
            Toast.makeText(context,a,Toast.LENGTH_LONG).show()
           // Log.e("收到消息", "a=$a=b=${b.reply("aaaa${System.currentTimeMillis()}")}")
        }
    }
    private fun getBatteryLevel(): Int {
        return 123
    }


}

完整dart 代码如下

import 'dart:async';

import 'package:flutter/material.dart';
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 StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String _batteryLevel = '';
  String _eventStr = '';
  String _mssageStr = '_mssageStr';
  static const platfrom = const MethodChannel("tip.flutter.io/method");
  static const eventChannel = const EventChannel("tip.flutter.io/event");
  static const messageChannel = const BasicMessageChannel<String>(
      "tip.flutter.io/message", StringCodec());
  StreamSubscription _streamSubscripton;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  Future<Null> _getBatteryLevel() async {
    String batteryLevel;
    try {
      final int result = await platfrom.invokeMethod("getBatteryLevel");
      batteryLevel = 'Battery level at $result % .';
    } on PlatformException catch (e) {
      batteryLevel = "Failed to get battery level: '${e.message}'.";
    }
    setState(() {
      _batteryLevel = batteryLevel;
    });
  }

  Future<Null> _msssage() async {
    messageChannel.setMessageHandler((String message) => Future<String>(() {
          print("收到native的消息$message");
          setState(() {
            _mssageStr = message;
          });
          return "收到native的消息$message";
        }));
    String ponse;
    try {
      ponse = await messageChannel.send("我来自flutter");
    } catch (e) {
      print(e);
    }
    setState(() {
      _mssageStr = ponse;
    });
    print(ponse);
  }

  Future<Null> _lisEvent() async {
    String eventStr;
    try {
      _streamSubscripton = eventChannel
          .receiveBroadcastStream()
          .listen(_onToDart, onError: _onToDartError);
    } on PlatformException catch (e) {
      eventStr = "event get data err: '${e.message}'.";
      setState(() {
        _eventStr = eventStr;
      });
    }
  }

  @override
  void dispose() {
    if (_streamSubscripton != null) {
      _streamSubscripton.cancel();
      _streamSubscripton = null;
    }

    // TODO: implement dispose
    super.dispose();
  }

  _onToDart(message) {
    setState(() {
      _eventStr = message;
    });
    print(message);
  }

  _onToDartError(error) {
    print(error);
  }

  @override
  void initState() {
    // TODO: implement initState
    _getBatteryLevel();
    _lisEvent();
    _msssage();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
   
    return Scaffold(
      appBar: AppBar(
        
        title: Text(widget.title),
      ),
      body: Center(
        
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'AAA You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            Text(
              '$_batteryLevel',
            ),
            Text(
              '$_eventStr',
            ),
            Text(
              '$_mssageStr',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

c盘

  1. 修改.gradle 目录
    在Windows的环境变量中新建一个环境变量设置,GRADLE_USER_HOME,值为D:\Users\shaowei.gradle,
    设置完成之后,点击确定,关闭设置窗口。这个时候可以去AS中看下gradle的用户目录,自动变成了环境变量中的值了
  2. 修改配置文件Pixel_3_XL_API_28.ini
    avd.ini.encoding=UTF-8
    path=D:\avd\Pixel_3_XL_API_28.avd
    path.rel=avd\Pixel_3_XL_API_28.avd
    target=android-28
发布了96 篇原创文章 · 获赞 12 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/yujunlong3919/article/details/97175756