美文网首页
flutter学习笔记(二)

flutter学习笔记(二)

作者: AJI大侠 | 来源:发表于2018-07-31 22:06 被阅读46次

    本地访问-MethodChannel

    1. 本地访问是指跨平台的解决方案,有访问本地android或者ios资源的能力,主要是MethodChannel和MessageChannel两种,第一种是调用方法,第二种是传递信息。通信的双方是Flutter和本地操作系统或者应用,而且方法的调用和消息的方法可以从任何一方发起,类似远程过程调用。
    • Flutter是一个比较独立的环境,要想访问本地的资源,Flutter提供了Channel机制,类似Cilent-Server模式或者RPC
    • 通过Channel的名称打通Channel,隧道
    • Flutter和本地是对称的,请求可以从任何一发发起,这篇文章主要是记录从Flutter给本地发送请求

    • 首先我们创建Flutte工程,ide随你自己喜欢,修改UI代码如下:
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'dart:async';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      final String title;
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
      static const platformMethodChannel = const MethodChannel("com.xyjy.flutterchannel/test");
      num nativeMessage = 0;
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      Future<Null> getData() async{
        num _message;
          try{
            final num result = await platformMethodChannel.invokeMethod("getTime");
            _message = result;
          }
          on PlatformException catch(e){
            print(e.message);
          }
          setState(() {
            nativeMessage = _message;
          });
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            // Here we take the value from the MyHomePage object that was created by
            // the App.build method, and use it to set our appbar title.
            title: new Text(widget.title),
          ),
          body: new Center(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Text(
                  "$nativeMessage",
                ),
                new Text(
                  '$nativeMessage',
                  style: Theme.of(context).textTheme.display1,
                ),
              ],
            ),
          ),
          floatingActionButton: new FloatingActionButton(
            onPressed: ()=>getData(),
            tooltip: 'Increment',
            child: new Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
    
    • 很简单我只是将_counter显示的替换成了自己定义的nativeMessage,接着往下
    1. 首先我们要引入service包和async包。
      import 'package:flutter/services.dart';
      import 'dart:async';
    
    1. 声明一个static const变量platformMethodChannel ,赋值MethodChannel类型的对象。
     class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
      static const platformMethodChannel = const MethodChannel("com.xyjy.flutterchannel/test");
      num nativeMessage = 0;
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
    1. 在上面我们要注意,给MethodChannel一个名字com.xyjy.flutterchannel/test,这个名字和本地(这里代表android部分)那边的要一样
      我们创建了MethodChannel,我们准备一个用来发送请求的函数。我们创建一个叫getData的异步函数
      await platformMethodChannel.invokeMethod('getTime') 是调用本地的getTime方法,并且这个方法是异步的,await表示阻塞执行。
      nativeMessage = _message; 表示通知Flutter状态改变,刷新界面。
     Future<Null> getData() async{
        // num是数字类型
        num _message;
          try{
            final num result = await platformMethodChannel.invokeMethod("getTime");
            _message = result;
          }
          on PlatformException catch(e){
            print(e.message);
          }
          setState(() {
            nativeMessage = _message;
          });
      }
    
    1. 修改build里面的显示,将_counter 替换为nativeMessage ,并将floatingActionButton的onTap事件替换为我们定义好的getData方法
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            // Here we take the value from the MyHomePage object that was created by
            // the App.build method, and use it to set our appbar title.
            title: new Text(widget.title),
          ),
          body: new Center(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Text(
                  "$nativeMessage",
                ),
                new Text(
                  '$nativeMessage',
                  style: Theme.of(context).textTheme.display1,
                ),
              ],
            ),
          ),
          floatingActionButton: new FloatingActionButton(
            onPressed: ()=>getData(),
            tooltip: 'Increment',
            child: new Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    
    
    1. 接下来本地方法如何编写,打开MainActivity
     public class MainActivity extends FlutterActivity {
      private static final  String CHANNAL = "com.xyjy.flutterchannel/test";
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(this);
        new MethodChannel(getFlutterView() , CHANNAL).setMethodCallHandler(new MethodChannel.MethodCallHandler()
        {
          @Override
          public void onMethodCall(MethodCall methodCall, MethodChannel.Result result)
          {
              if (methodCall.method.equals("getTime"))
              {
                  long time = getTime();
                  result.success(time);
              }
              else
              {
                result.notImplemented();
              }
          }
        });
      }
    
      private long getTime()
      {
        return System.currentTimeMillis();
      }
    
    }
    
    • CHANNAL 里面的字符串一定是与Flutter定义一致,在MethodChannel的中调用.setMethodCallHandler() 方法,需要一个MethodCallHandler 对象,是一个匿名内部类,有一个方法onMethodCall,在Flutter发送请求时,onMethodCall方法会执行, result.success(time);返回信息,这样就可以进行本地调用,点击悬浮按钮得到时间(此时的时间是通过本地返回的时间)


      QQ图片20180709174145.png

    相关文章

      网友评论

          本文标题:flutter学习笔记(二)

          本文链接:https://www.haomeiwen.com/subject/bdytpftx.html