eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

kotlin-coroutines 0.26.1での破壊的更新

coroutines 0.26.1の変更点

  • 多くのクラスやトップレベルfunctionやプロパティがdeprecatedになった

変更から見える方針

  • トップレベルの関数やプロパティを、いずれかのobject等に所属させることが主な目的に見える

主なDeprecated

  • UI, CommonPool 等の標準Dispatcherが非推奨
    • Dispatchers.Main, Dispatchers.Default が追加された
  • launch{}, async{} 等のトップレベル関数が非推奨
    • GlobalScope.launch, GlobalScope.async が追加された
  • isActive が拡張関数になった
    • ビルドが通らないので、ガイドに従って書き換える

互換性

  • Deprecated属性になっただけで、0.24のときのような内部の破壊的仕様変更はされていない
  • 様子見しつつ、移行して行こう。

移行時の注意

  • GlobalScope.launchCoroutineScope.launch を使い分ける
    • CoroutineScope.thisが届く範囲のlaunch/async等はそのまま動作する
    • 「とりあえずlaunchって書けば非同期になるよ」みたいなことが言えなくなる
  • Android Studioの場合、 Alt + Enter で移行先を示してくれる
    • UIDispatchers.Main にしてくれたり、いろいろ
    • デフォルト引数が設定されている場合、勝手にデフォルト値が転記されてしまうので、全自動は無理
    • CommonPoolは補完されないので手動で Dispatchers.Default にする
  • withContext{} で渡されるthisのスコープが変わった
    • ブロック内でフィールド変数にアクセスしてる場合、スコープ範囲外でエラーになる
    • this@HogeFuga.fieldName = Hoge みたいに書き換える

悲観的推測

  • GlobalScopeの場合とCoroutineScope.thisのLaunchでJobの親子関係が異なるかもしれない?
    • ちゃんと移行しないと、 job.cancel() の挙動とかに影響あるかも
  • 0.24 -> 0.25のときのように破壊的変更が次期バージョンでRevertされる恐れもある

Google Play Services Gradle Plugin 4.1.0の問題点

既知の問題点

  • Gradle Pluginバージョンは com.android.tools.build:gradle:3.3.0-alpha10
  • google-services.jsonを検索しない
    • 考えうる限りいろんなpathにおいたけど反応なし
    • ログも --debug オプションで見たが吐き出されない
  • 完全にnot workingらしい
  • 4.0.2は期待通り動作する

諦めた

  • アップデートに期待する

AS3.3 canary-11の問題点

問題点

  • Find Action(Ctrl + Shift + A)が正常動作しない
  • たまに正常動作する
  • だいたい正常動作しない
  • Crash Reportが吐き出されてるので、どっかのPluginと競合している
    • Reportは送った
  • 以前はFlutter Pluginと競合していたので、uninstall済み
  • Dartも怪しかったのでuninstallしたが、改善されず

諦めた

  • C12に期待する

QRコードをスキャンする仕様で注意すべきこと

QRコードもカメラも物理デバイスである

  • QRコードは対象物の物理サイズにも留意して作成する
  • 小さすぎると、カメラに映ってもオートフォーカスが正常動作しない場合がある
    • レンズが汚れていると更に辛い
  • フロントカメラは概ね低スペックなので、バックカメラよりも気を使う

実例

  • Nexus9のフロントカメラで18mm角だとスキャンに成功する
  • 16mm角前後だとスキャンに成功する個体・失敗する個体に別れ始める

今後のために

  • 物理的な大きさと距離について、無制限ではないという点に留意して仕様を考える

VIVITA社に転職しました

FROM

以前のエントリーの通り、8月31日で TOPGATE社 を退職しました。

TO

9月1日から、 VIVITA 所属となり、子どもたちがアイディアを形にするための環境づくりを行います。

Androidアプリ開発やサーバー開発といった形で参加する予定です。

ほしいものリスト

(/ω・\)チラッ

http://amzn.asia/66X0Vi3

CIや開発時のビルドタスク管理にfastlaneを導入した

導入前

  • shellスクリプトを必要に応じて書いていた
  • どういうビルドタスクやスクリプトがあるのか、ドキュメントが面倒だった

導入した理由

  • ビルドタスクの一覧性を担保できる
    • fastlane list でタスク一覧が表示される
    • タスクを分類できる
      • fastlane platform_foo task_bar
  • Androidに対応している
    • Gradleタスクは簡単に実行できる
    • bundle, apkのアップロードが簡単に行える
  • 内部でシェルを実行できる
    • どうしても移行が難しいタスクは、内部でシェルをkickすれば良い

導入後の問題点

  • fastlaneを導入しなければならない
    • rubyやbundleと一緒に導入なので、開発しているOSによっては制限がある
  • rubyを覚えなければならない
    • 慣れ
  • 開発 / ビルド用のDocker Imageが300MB程度大きくなる

coroutines 0.24.x runBlockingの仕様変更と対策

変更されたこと

  • runBlockingがUIスレッドからの呼び出しで例外を投げるようになった
    • UnitTestの内部とかで使ったり、無理矢理coroutinesのChannelとかを待ち合わせる用途に使えなくなった
  • 特にJVMでのUnitTestで使ってたので、全部死んだ
// この呼び出しはすべて例外となる
// 23.x系列までは使える
// 24.x系列からは駄目

@Test
fun testHogeFuga() = runBlocking { /* do something */ }

runBlockingの仕様変更に関するissue

issue Support runBlocking for UI Tests

  • コレは意図した変更なので、多分不可逆じゃないかな、とは思う
  • coroutineの処理実装から考えると、特定のシングルスレッドをブロックするのは好ましくない
    • 待機しているcoroutineの処理ブロックが回らなくなる

解決方法

// 最初に呼び出す
init {
    System.setProperty(BLOCKING_CHECKER_PROPERTY_NAME, BLOCKING_CHECKER_VALUE_DISABLE)
}
  • もしくは0.23.x系列までを使用する
  • もしくはUIスレッド対応のrunBlockingを用意する
  • さらに面倒をするなら、BlockingCheckerを自前で実装してそちらを使うように迂回させる
    • この方法は用意されてるけども面倒なのでskip

CoroutineScope.coroutineContextが非推奨

  • suspendブロック内のthis.coroutineContextが非推奨になった
  • トップレベルプロパティとして kotlin.coroutines.experimental.coroutineContext が生まれているので、それを利用する