2019/07/25
Mix Leap Study #47 - Android x Flutter 勉強会
Flutterとプラットフォーム依存の処
理の対応について
GDG神戸オーガナイザー 野田 悟志
自己紹介
自己紹介
GDG神戸オーガナイザー(Manager) (2015~)
● 仕事
コミュニケーションロボットSota(ソータ)の内部コンテンツ、クラウド周
り開発
● 趣味:VR
Oculus Rift DK2、Oculus Rift CV1、Cardboard、PSVR、
FOVE 0、Daydream、FirstVR(UnlimitedHandLite)、
Oculus Go、Oculus Quest ← New!!
自己紹介
仕事:Sota連携API
NTT東サービス「ロボコネクト」版のSotaを、
REST API(っぽいやつ)で操作できる仕組
み。
ソフトエンジニア向けで、モバイルアプリなど
の自社サービスを、ロボットで身体性のある
サービスに展開したい人向け(法人のみ)。
Flutter
Flutter
Flutterとは
Flutterは、単一のコードベースから高性能で高忠実度(OSバージョンに
UIが影響されない)の、iOSおよびAndroid用のアプリケーションを構築
するためのモバイルアプリSDK。
開発者がさまざまなプラットフォームで自然に感じる高性能アプリケー
ションを提供できるようにすることを目標としている。例えば、スクロール
動作、タイポグラフィ、アイコンなどの違いを解決する。
https://flutter.dev/docs/resources/technical-overview#what-is-flutter
Flutter
なぜFlutterを使うのか
● 生産性が高い
○ 単一のコードベース(Dart)からiOSとAndroid用に開発できる
○ より少ないコードでより多くのことができる
○ プロトタイプを簡単に繰り返すことができる
■ アプリの実行中にコードを変更してリロードすることができ
る(ホットリロード)
■ クラッシュを修正し、アプリが中断したところからデバッグ
を続行することができる
Flutter
なぜFlutterを使うのか
● カスタマイズされた美しいユーザーエクスペリエンスを作成すること
ができる
○ Flutter独自のフレームワークを使用して構築された豊富な
Material DesignおよびCupertino(iOSフレーバー)ウィジェット
の恩恵を受けることができる
○ OEMウィジェットを使用せず(つまりOSバージョンにUIが影響さ
れない)、カスタムで美しい、ブランド主導のデザインを実現でき
る
https://flutter.dev/docs/resources/technical-overview#why-use-flutter
Flutter
なぜFlutterを使うのか
https://flutter.dev/docs/resources/technical-overview#layer-cakes-are-delicious
Flutter
豊富なパッケージ
依存パッケージはpubspec.yamlに記載する。
dependencies:
flutter:
sdk: flutter
firebase_analytics: ^1.0.3
shared_preferences: ^0.4.3
下記からパッケージを探せる。かなり多くのパッケージが存在しており、
だいたいがAndroid、iOSに対応している。
https://pub.dev/flutter
Flutter
Flutterをはじめる
Flutterをはじめる時は、コードラボをやるのがおススメ。
https://codelabs.developers.google.com/?cat=Flutter
● Intro to Dart for Java Developers
○ Dartの基本的な文法が学べる
● Write Your First Flutter App, part 1
● Write Your First Flutter App, part 2
○ Part1, 2を通して、Flutterの基本的な実装方法が学べる
● Firebase for Flutter
○ FlutterでFirebaseを使う場合が学べる
Flutter
Flutterをはじめる
Flutterがどういうもので、どこがいいのかは「What’s Revolutionary
about Flutter」の日本語翻訳版も参考になる。
https://qiita.com/yasutaka_ono/items/21a5a55c1ff81740f9e4
Platform Channels
よし。だいたいわかった。とはいえ…
Flutterが良さそうなのは分
かったけど、実際に開発す
る時にネイティブコード触り
たい時ってあるよね…
そんなあなたにおススメしたいのが
Platform
Channels
Platform Channels
概要
Flutterコード(Dart)と、AndroidまたはiOSのネイティブコード(Kotlin、
Swiftなど)との通信の仕組み。
Platform Channelsを介して、Flutter側からネイティブコード側にメッ
セージを送信し、ネイティブコード側はメッセージを受信した後、ネイティ
ブコードでの処理を実行し、そのレスポンスをFlutter側に返す、というこ
とが出来る。
https://flutter.dev/docs/development/platform-integration/platform-ch
annels
Platform Channels
実例:Flutter(Dart)側
// チャンネル名(任意のキー文字列 )を設定する
static const platform = const MethodChannel('samples.flutter.dev/battery');
// 呼び出すメソッド名 (任意のキー文字列 )を指定する
// (引数がある場合は、第二引数に Map<String, dynamic>で指定する)
final int result = await platform.invokeMethod('getBatteryLevel');
Platform Channels
実例:Androidネイティブコード(Kotlin)側
private val CHANNEL = "samples.flutter.dev/battery"
// 指定したチャンネル名の MethodCallHandlerを登録する
MethodChannel(flutterView, CHANNEL).setMethodCallHandler { call, result ->
// ここの処理はメインスレッドで実行される
// 呼び出したメソッド名によって処理を実行する。 (引数はObject型でcall.argumentsでとれる)
if (call.method == "getBatteryLevel") {
val batteryLevel = getBatteryLevel() // ここではバッテリー値取得メソッドを呼んでいる
// 戻り値の設定
result.success(batteryLevel)
} else {
result.notImplemented()
}
}
Platform Channels
実例:Androidネイティブコード(Java)側
private static final String CHANNEL = "samples.flutter.dev/battery";
// 指定したチャンネル名の MethodCallHandlerを登録する
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
// 呼び出したメソッド名によって処理を実行する。 (引数はObject型でcall.argumentsでとれる)
if (call.method.equals("getBatteryLevel")) {
int batteryLevel = getBatteryLevel(); // ここではバッテリー値取得メソッドを呼んでいる
// 戻り値の設定
result.success(batteryLevel);
} else {
result.notImplemented();
}
}
});
これでネイティブコードが書ける!
※幸せ感には個人差があります
ところで…
逆に、ネイティブコードから
Flutterコードを呼び出した
い時ってあるよね?
Platform Channels
ネイティブコードからメッセージ送信
Platform Channelsを介して、ネイティブコード側から、Flutter側にメッ
セージを送信することもできる。
Flutter側で共通処理を実装し、それをネイティブコードから呼ぶといった
使い方ができる。
Platform Channels
実例:Androidネイティブコード(Kotlin)側
// チャンネル名(任意のキー文字列 )
private static final String CALLBACK_CHANNEL = "samples.flutter.dev/callback";
// 呼び出すメソッド名 (任意のキー文字列 )を指定する
// (引数がある場合は、第二引数に指定する )
MethodChannel(flutterView, CALLBACK_CHANNEL).invokeMethod("callback", null)
Platform Channels
実例:Androidネイティブコード(Java)側
// チャンネル名(任意のキー文字列 )
private static final String CALLBACK_CHANNEL = "samples.flutter.dev/callback";
// 呼び出すメソッド名 (任意のキー文字列 )を指定する
// (引数がある場合は、第二引数に指定する )
new MethodChannel(getFlutterView(), CALLBACK_CHANNEL).invokeMethod("callback", null);
Platform Channels
実例:Flutter(Dart)側
// 指定したチャンネル名の MethodChannelを生成する
static const platformCallback = const MethodChannel('samples.flutter.dev/callback');
// 指定したチャンネル名の MethodCallHandlerを登録する
platformCallback.setMethodCallHandler((MethodCall call) async {
if (call.method == "callback") {
// 処理を実行
// 引数はcall.argumentsでdynamic型でとれる
}
});
Platform Channels
注意点
Platform ChannelsはFlutterView(または
FlutterViewController)の
MethodChannelを使用している。
そのため、AndroidならActivityが生きている
(フォアグラウンド、またはバックグラウンド)状
態でなければならない。
Platform Channels
注意点
もし、FlutterViewが存在しない場合、例外は発生しないが、
FlutterViewが存在しないというエラーメッセージが出力される。
音楽プレイヤーなど、AndroidでネイティブコードでServiceを実装し、
バッググラウンドで実行しているときに、Activityを破棄すると、Flutter
側にメッセージを送ること(受け取ること)はできない。
かくいう僕も…
実は困らない…?
AmazonMusicアプリは
Activity破棄すると音楽再生
できない(止まる)から、Flutter
で音楽プレイヤーを作る場合
は、問題にならないのかも?
Android、iOSやってないので
分かりません。
ご清聴ありがとうございました

Flutterとプラットフォーム依存の処理の対応について