由于我不会做IOS开发,文章里面没有IOS的代码。下面的参考教程里有具体的IOS代码 参考教程:flutter中文网–Flutter实战–插件开发,平台介绍和实现Android端API
最后的执行效果如下:
平台指的是flutter运行的平台,如Android或者ios,可以认为就是应用的原生部分,所以,平台通道正是Flutter和原生之间通信的桥梁,它也是Flutter插件的底层基础设施。
Flutter使用了一个灵活的系统,允许调用特定平台的API,无论在Android上的Java或者Kotlin代码中,还是在IOS上的OC或者swift代码中均可用。
Flutter与原生之间的通信依赖灵活的消息传递方式:
应用的Flutter部分通过平台通道(platform channel)将消息发送到其应用程序所在的宿主(IOS或者Android)应用(原生应用)宿主监听平台通道,并接受该消息,然后它会调用该平台的API,并将响应发送回客户端,即应用程序的Flutter部分。使用平台通道在Flutter(client)和原生(host)之间传递消息,如下图所示:
当在Flutter中调用原生方法时,调用信息通过平台通道传递到原生,原生收到调用信息后可以执行指定的操作,如果需要返回数据,则原生会将数据再通过平台通道传递给Flutter,需要注意的是消息的传递是异步的,这确保了用户界面再消息传递时不会被挂起。
在客户端,MethodChannel API可以发送与方法调用相对应的消息,在宿主平台上,MethodChannel在Android API和FlutterMethodChannel IOS API可以接收方法调用并返回结果,这些类可以帮助我们用很少的代码就能开发平台插件。
如果需要,方法调用(消息传递)可以是反向的,即宿主作为客户端调用Dart中实现的API,quick_actions插件就可以这么做。
使用平台通道调用原生代码
下面是一个获取电池电量的插件,该插件在Dart中通过getBatteryLevel调用Android BatteryManager API和IOS的相关API。
Flutter中的代码如下:
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; /** * 插件开发--获取宿主平台的电量信息 */ class BetteryInfoPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( "插件开发--获取电量", style: TextStyle( color: Colors.greenAccent, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), elevation: 0.0, backgroundColor: Colors.lime, ), body: BetteryInfoRoute(), ); } } class BetteryInfoRoute extends StatefulWidget { @override _BetteryInfoRouteState createState() { return _BetteryInfoRouteState(); } } class _BetteryInfoRouteState extends State with SingleTickerProviderStateMixin { static const platform = const MethodChannel("samples.flutter.io/battery"); //默认电量100% double _currentBetteryInfo = 100; //当前的文字颜色,根据不同的电量改变 Color _betteryColor = Colors.greenAccent; //动画控制器 AnimationController _animationController; //动画 Animation _animation; //显示当前获取电量的状态信息 String _currentState = "正在获取信息"; @override void initState() { // TODO: implement initState super.initState(); setBatteryColor(); getValueColorAnimation(); _getBatteryLevel(); } @override Widget build(BuildContext context) { //一个圆形进度条中间显示电量的百分比 return Center( child: Stack( alignment: Alignment.center, children: <Widget>[ Container( constraints: BoxConstraints.expand(width: 120.0, height: 120.0), child: CircularProgressIndicator( backgroundColor: Colors.redAccent, valueColor: _animation, value: _currentBetteryInfo / 100, ), ), Padding( padding: EdgeInsets.all(10.0), child: Text( _currentState, style: TextStyle( color: _betteryColor, ), ), ), ], ), ); } //设置动画 void getValueColorAnimation() { if (_animationController == null) { _animationController = AnimationController(duration: Duration(seconds: 5), vsync: this); } _animation = CurvedAnimation(parent: _animationController, curve: Curves.ease); _animation = Tween(begin: _betteryColor, end: Colors.greenAccent) .animate(_animation); } //设置不同电量的颜色 void setBatteryColor() { if (_currentBetteryInfo > 80) { _betteryColor = Colors.greenAccent; } else if (_currentBetteryInfo > 50) { _betteryColor = Colors.orangeAccent; } else { _betteryColor = Colors.redAccent; } } //获取电量 Future<Null> _getBatteryLevel() async { try { _currentBetteryInfo = await platform.invokeMethod("getBatteryLevel"); _currentState = "${_currentBetteryInfo.toString()}%"; } on PlatformException catch (e) { //出现异常 _currentState = "failed"; } finally { //最终都会执行刷新操作 setState(() { setBatteryColor(); getValueColorAnimation(); }); } } }//Android中的代码如下:
package com.example.basicwidgetdemo1; import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.Build; import android.os.Bundle; import io.flutter.app.FlutterActivity; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity { private static final String CHANNEL = "samples.flutter.io/battery"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler( new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { if(methodCall.method.equals("getBatteryLevel")){ double batteryLevel = getBatteryLevel(); if(batteryLevel != -1){ result.success(batteryLevel); }else{ result.error("UNAVAILABLE","Battery level not available",null); } }else{ result.notImplemented(); } } } ); } //获取手机剩余电量 private double getBatteryLevel(){ double battery = -1; if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ BatteryManager manager = (BatteryManager) getSystemService(BATTERY_SERVICE); battery = manager.getLongProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY); }else{ Intent intent = new ContextWrapper(getApplicationContext()).registerReceiver(null,new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); battery = intent.getIntExtra(BatteryManager.EXTRA_LEVEL,-1) / intent.getIntExtra(BatteryManager.EXTRA_SCALE,-1); } return battery; } }