はじめに
どうしてもFlutterを書いているとDartだけで表現できないこともおきてくるので、各ネイティブ処理呼べたらなーと思ってました。わざわざFlutterのプロジェクトを生成するときに各OSのフォルダあるしできるやろと思って調べたらやっぱりありました。
ここに書いてあることはplatform-channels全部書いてあったりしますが、その点はご了承ください。
iOSの環境作成をずっと面倒くさがってAndroidの話だけしか書いてません。
環境
Flutter 1.0
Android Studio
Dart側の対応
まず必要なパッケージをimportします。
import 'package:flutter/services.dart';
そしてメンバ変数としてMethodChannel
を宣言しておきます。
引数は後々使うので、分かりやすい名前にしておきましょう。(以下チャンネル名と書きます。)
static const platform = const MethodChannel('com.tasogarei.test/web');
次に呼び出し口です。
わざわざ処理を呼び出したいので、たいていは状態変化させる箇所に書くことになるかと思います。
今回は読んだ先の日付を文字列でもらってsetState
する感じにします。
ここから呼び出しますが、呼び出し方は簡単でplatform.invokeMethod('web')
とするだけです。
引数は識別子になりますので、これもわかるようにしておいてください。
void _incrementCounter() async {
String dateString = await platform.invokeMethod('web');
setState(() {
_title = dateString;
});
}
Kotlin側の対応
まずはFlutter作成時のbuild.gradle
とかに書いてあるバージョンは基本的に古いので、いい感じに修正する必要があります。(ここでは割愛)
まずはKotlin側のソースを全部のせておきます。
package com.tasogarei.flutterapp2
import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
import java.time.LocalDateTime
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
MethodChannel(flutterView, "com.tasogarei.test/web").setMethodCallHandler { call, result ->
when(call.method) {
"web" -> {
result.success(LocalDateTime.now().toString())
}
}
}
}
}
今回肝となるコードはその中でこの部分になります。
MethodChannel(flutterView, "com.tasogarei.test/web").setMethodCallHandler { call, result ->
when(call.method) {
"web" -> {
result.success(LocalDateTime.now().toString())
}
}
}
ここで先ほどDartファイル側で設定しておいたチャンネル名と識別子が設定されます。
MethodChannel
の第二引数にチャンネル名を渡すことで大元を識別し、そのCallHandler内で識別子を判定して処理させていきます。
Kotlin側からDart側へ結果を戻す際にはresult
内に結果を詰め込むためのメソッドが用意されているので、それに結果を入れてあげるだけです。
resultの型はデータクラスではPlatformException(error, Unsupported value: Data(id=1, name=name), null)
と出てダメだったので、文字列とか数字じゃないとダメそうです。
複雑なデータの場合はJson使用してやり取りするしか現状はなさそうです。