Flutter與原生的交互主要經過MethodChannel的方式
本文只列舉兩種形式的插件,掌握基礎的插件寫法,觸類旁通,例如我github項目中的高德定位,6.0以上權限申請等,還須要掌握iOS的的基礎語言o c,swift才能編寫iOS插件。git
效果GIF
Channel.gifgithub
從Flutter界面跳轉到原生,且帶參數
1. 實現插件swift
public class FlutterPluginJumpToAct implements MethodChannel.MethodCallHandler { public static String CHANNEL = "com.jzhu.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(); } } }
2. 插件註冊async
須要在繼承了FlutterActivity中的Activity註冊ide
public class MainActivity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); registerCustomPlugin(this); } private static void registerCustomPlugin(PluginRegistry registrar) { FlutterPluginJumpToAct.registerWith(registrar.registrarFor(FlutterPluginJumpToAct.CHANNEL)); FlutterPluginCounter.registerWith(registrar.registrarFor(FlutterPluginCounter.CHANNEL)); } }
3. 帶參數跳轉學習
//獲取到插件與原生的交互通道 static const jumpPlugin = const MethodChannel('com.jzhu.jump/plugin'); 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); }
參數解釋
1. 傳遞的參數this
參數能夠不指定類型spa
Future<dynamic> invokeMethod(String method, [dynamic arguments]) async { assert(method != null); final dynamic result = await BinaryMessages.send( name, codec.encodeMethodCall(new MethodCall(method, arguments)), ); if (result == null) throw new MissingPluginException('No implementation found for method $method on channel $name'); return codec.decodeEnvelope(result); }
2. 解析傳遞的參數插件
解析的參數是泛型debug
public <T> T arguments() { return this.arguments; } public <T> T argument(String key) { if (this.arguments == null) { return null; } else if (this.arguments instanceof Map) { return ((Map)this.arguments).get(key); } else if (this.arguments instanceof JSONObject) { return ((JSONObject)this.arguments).opt(key); } else { throw new ClassCastException(); } }
原生主動發送參數給Flutter
1. 實現插件
public class FlutterPluginCounter implements EventChannel.StreamHandler { public static String CHANNEL = "com.jzhu.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); } @Override public void onListen(Object o, final EventChannel.EventSink eventSink) { Observable.interval(1000, TimeUnit.MILLISECONDS).subscribe(new Observer<Long>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Long aLong) { eventSink.success(aLong.intValue()); } @Override public void onError(Throwable e) { eventSink.error("計時器異常", "異常", e.getMessage()); } @Override public void onComplete() { } }); } @Override public void onCancel(Object o) { Log.i("FlutterPluginCounter", "FlutterPluginCounter:onCancel"); } }
2. Flutter接收原生髮送的參數
static const counterPlugin = const EventChannel('com.jzhu.counter/plugin'); StreamSubscription _subscription = null; var _count; @override void initState() { super.initState(); //開啓監聽 if(_subscription == null){ _subscription = counterPlugin.receiveBroadcastStream().listen(_onEvent,onError: _onError); } } @override void dispose() { super.dispose(); //取消監聽 if(_subscription != null){ _subscription.cancel(); } } void _onEvent(Object event) { setState(() { _count = event; print("ChannelPage: $event"); }); } void _onError(Object error) { setState(() { _count = "計時器異常"; print(error); }); }
備註 : debug模式原生跳轉到flutter界面會出現白屏,release包就不會出現白屏了!!!
已有項目集成到Flutter代碼已經上傳到個人GITHUB
知乎日報Flutter版代碼已經上傳到個人GITHUB
基礎學習過程當中的代碼都放在GITHUB
天天學一點,學到Flutter發佈正式版!
做者:老實巴交的讀書人 連接:https://www.jianshu.com/p/c5263a3d7aac 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。