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

相關文章
相關標籤/搜索