Flutter知識點: Flutter與原生(Android)的互動
阿新 • • 發佈:2018-12-30
Flutter與原生的互動主要通過MethodChannel的方式
本文只列舉兩種形式的外掛,掌握基礎的外掛寫法,舉一反三,例如我github專案中的高德定位,6.0以上許可權申請等,還需要掌握iOS的的基礎語言o c,swift才能編寫iOS外掛。
效果GIF
Channel.gif
從Flutter介面跳轉到原生,且帶引數
1. 實現外掛
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. 外掛註冊
需要在繼承了FlutterActivity中的Activity註冊
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. 傳遞的引數
引數可以不指定型別
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. 解析傳遞的引數
解析的引數是泛型
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);
});
}