Flutter和原生交互學習

 

PlatformChannel功能簡介

PlatformChannel分爲BasicMessageChannel、MethodChannel以及EventChannel三種。其各自的主要用途以下:android

  • BasicMessageChannel: 用於傳遞數據。Flutter與原生項目的資源是不共享的,能夠經過BasicMessageChannel來獲取Native項目的圖標等資源。
  • MethodChannel: 傳遞方法調用。Flutter主動調用Native的方法,並獲取相應的返回值。好比獲取系統電量,發起Toast等調用系統API,能夠經過這個來完成。
  • EventChannel: 傳遞事件。這裏是Native將事件通知到Flutter。好比Flutter須要監聽網絡狀況,這時候MethodChannel就沒法勝任這個需求了。EventChannel能夠將Flutter的一個監聽交給Native,Native去作網絡廣播的監聽,當收到廣播後藉助EventChannel調用Flutter註冊的監聽,完成對Flutter的事件通知。

其實能夠看到,不管傳方法仍是傳事件,其本質上都是數據的傳遞,不過上層包的一些邏輯不一樣而已。網絡

 

flutterapp

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

class ChannelPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new _ChannelPageState();
  }
}

class _ChannelPageState extends State<ChannelPage> {

  //獲取到插件與原生的交互通道
  static const jumpPlugin = const MethodChannel('com.example.jump/plugin');
  static const counterPlugin = const EventChannel('com.example.counter/plugin');
  var _count;
  StreamSubscription _counterSub;
  @override
  void initState() {
    super.initState();
    _startCounterPlugin();
  }

  @override
  void dispose() {
    super.dispose();
    _endCounterPlugin();
  }
  void _startCounterPlugin(){
    if(_counterSub == null){
      _counterSub =  counterPlugin.receiveBroadcastStream().listen(_onCounterEvent,onError: _onCounterError);
    }
  }

  void _endCounterPlugin(){
    if(_counterSub != null){
      _counterSub.cancel();
    }
  }
  void _onCounterError(Object error) {
    setState(() {
      _count = "計時器異常";
      print(error);
    });
  }

  void _onCounterEvent(Object event) {
    setState(() {
      _count = event;
    });
  }


  Future<Null> _jumpToNative() async {
    String result = await jumpPlugin.invokeMethod('oneAct');

    print(result);
  }

  Future<Null> _jumpToNativeWithValue() async {

    Map<String, String> map = { "flutter": "這是一條來自flutter的參數" };

    String result = await jumpPlugin.invokeMethod('twoAct', map);

    print(result);
  }


  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Channel"),
        centerTitle: true,
      ),
      body: new Center(
          child: new ListView(
            children: <Widget>[
              new Padding(
                padding: const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0),
                child: new RaisedButton(
                    textColor: Colors.black,
                    child: new Text('跳轉到原生界面'),
                    onPressed: () {
                      _jumpToNative();
                    }),
              ),
              new Padding(
                padding: const EdgeInsets.only(
                    left: 10.0, top: 10.0, right: 10.0),
                child: new RaisedButton(
                    textColor: Colors.black,
                    child: new Text('跳轉到原生界面(帶參數)'),
                    onPressed: () {
                      _jumpToNativeWithValue();
                    }),
              ),

              new Padding(
                padding: const EdgeInsets.only(
                    left: 10.0, top: 10.0, right: 10.0),
                child: new Text('這是一個從原生髮射過來的數據:$_count'),
              ),


            ],
          )
      ),
    );
  }
}

androidasync

package com.example.flutter_app.plugins;

import android.app.Activity;
import android.util.Log;


import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.PluginRegistry;


public class FlutterPluginCounter implements EventChannel.StreamHandler {

    public static String CHANNEL = "com.example.counter/plugin";

    static EventChannel channel;

    private Activity activity;


    private FlutterPluginCounter(Activity activity) {
        this.activity = activity;
    }

    public static void registerWith(PluginRegistry.Registrar registrar) {
        channel = new EventChannel(registrar.messenger(), CHANNEL);
        FlutterPluginCounter instance = new FlutterPluginCounter(registrar.activity());
        channel.setStreamHandler(instance);
       // basicMessageChannel = new BasicMessageChannel<String> ("foo", StringCodec.INSTANCE);
    }

    @Override
    public void onListen(Object o, final EventChannel.EventSink eventSink) {
        eventSink.success(123456);
    }

    @Override
    public void onCancel(Object o) {
        Log.i("FlutterPluginCounter", "FlutterPluginCounter:onCancel");
    }

}
package com.example.flutter_app.plugins;

import android.app.Activity;
import android.content.Intent;


import com.example.flutter_app.OneActivity;
import com.example.flutter_app.TwoActivity;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.PluginRegistry;

public class FlutterPluginJumpToAct implements MethodCallHandler {

    public static String CHANNEL = "com.example.jump/plugin";

    static MethodChannel channel;

    private Activity activity;

    private FlutterPluginJumpToAct(Activity activity) {
        this.activity = activity;
    }

    public static void registerWith(PluginRegistry.Registrar registrar) {
        channel = new MethodChannel(registrar.messenger(), CHANNEL);
        FlutterPluginJumpToAct instance = new FlutterPluginJumpToAct(registrar.activity());
        //setMethodCallHandler在此通道上接收方法調用的回調
        channel.setMethodCallHandler(instance);
    }

    @Override
    public void onMethodCall(MethodCall call, MethodChannel.Result result) {

        //經過MethodCall能夠獲取參數和方法名,而後再尋找對應的平臺業務,本案例作了2個跳轉的業務

        //接收來自flutter的指令oneAct
        if (call.method.equals("oneAct")) {

            //跳轉到指定Activity
            Intent intent = new Intent(activity, OneActivity.class);
            activity.startActivity(intent);

            //返回給flutter的參數
            result.success("success");
        }
        //接收來自flutter的指令twoAct
        else if (call.method.equals("twoAct")) {

            //解析參數
            String text = call.argument("flutter");

            //帶參數跳轉到指定Activity
            Intent intent = new Intent(activity, TwoActivity.class);
            intent.putExtra(TwoActivity.VALUE, text);
            activity.startActivity(intent);

            //返回給flutter的參數
            result.success("success");
        }
        else {
            result.notImplemented();
        }
    }

}
package com.example.flutter_app;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class OneActivity extends Activity implements View.OnClickListener {

    private Button mGoFlutterBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_one);

        mGoFlutterBtn = findViewById(R.id.go_flutter);

        mGoFlutterBtn.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.go_flutter:
                Intent intent = new Intent(this, MainActivity.class);
                startActivity(intent);
                break;
        }
    }

}
package com.example.flutter_app;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class TwoActivity extends Activity{

    private TextView mTextView;

    public static final String VALUE = "value";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_two);

        mTextView = findViewById(R.id.text);

        String text = getIntent().getStringExtra(VALUE);

        mTextView.setText(text);

    }

}
package com.example.flutter_app;

import android.os.Bundle;

import com.example.flutter_app.plugins.FlutterPluginCounter;
import com.example.flutter_app.plugins.FlutterPluginJumpToAct;

import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class MainActivity extends FlutterActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
    FlutterPluginJumpToAct.registerWith(this.registrarFor(FlutterPluginJumpToAct.CHANNEL));//註冊
    FlutterPluginCounter.registerWith(this.registrarFor(FlutterPluginCounter.CHANNEL));//註冊

  }
}

效果:ide

相關文章
相關標籤/搜索