通信用到的类
- MethodChannel
- EventChannel
- BasicMessageChannel
MethodChannel使用方式(flutter 调用原生方法)
1. 原生代码
- 定义通信标识
private val METHOD_CHANNEL = "tip.flutter.io/method"
- 创建对象
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() } }
- 定义原生方法
private fun getBatteryLevel(): Int { return 123 }
2. dart代码
- 创建对象
static const platfrom = const MethodChannel("tip.flutter.io/method");
- 初始化方法
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; }); }
- 调用方法
@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: bbfx89625@gmail.com * 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盘
- 修改.gradle 目录
在Windows的环境变量中新建一个环境变量设置,GRADLE_USER_HOME,值为D:\Users\shaowei.gradle,设置完成之后,点击确定,关闭设置窗口。这个时候可以去AS中看下gradle的用户目录,自动变成了环境变量中的值了- 修改配置文件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