Kotlin Fest 2019に参加してきました

Kotlin Festの感想ブログを読んでいて、やっぱり自分も書きたくなっちゃった。だから書く。(2年連続)

去年の記事

shiraji.hatenablog.com

CfP

今年はCfPだったので、2本書きました。

  • GraphQL周り(通過した話)
  • IntelliJ周り(DroidKaigiでなかなか反応良かった話の改良版)

セッションの内容に新規性・独自性があること Kotlin独自の知見を得られること ― 例えば内容をJavaに置き換えても同じ知見が得られるようなセッションは採用されにくいです。

これらの要件が本当に難しくて、Javaに置き換えられない内容ってCoroutineやKotlinでしか使えないライブラリしかないんでは?と悩みまくりました。それに加えて新規性!?とかなり苦しんだCfPでした。

通過連絡

7/10に通過連絡が来ました。

全然時間なかった!とここで文句書くつもりだったけど、メール確認して7/10に連絡来ていた事実を知り、1.5ヶ月もあったんなら余裕だったんじゃん・・・と今反省しています。いや、夏休みがあったから実質1ヶ月だしやっぱり時間なかった!

スライド準備

CfPの時にアウトラインが決まっていたこともあり、サクサク進むかなーって思ってました。 IntelliJの話がしたくてしたくて、その影響もあり、あんまりモチベーションが上がらず、進捗は良くなかったです。 7月から話す内容を書き出し、2週間前にKeynoteの1枚目を作り出し、1週間前にようやく完成しました。

かなり遅くて焦ったのですが、今までとは別の方法でスライド作成し、その方法が自分には結構フィットしました。これは自分にとってかなり大きな収穫かなーと考えています。

前日

去年同様、ぼっち飯回避ツイートをしました。

kouさん、ikkunさんが反応してくれたので、前日の時点でぼっち飯回避できたの本当に良かった。

当日に追加で呼びかけたらいっせいさんが反応してくれました。これで準備万端になりました!

当日

会場に入ったのは10:40くらいでした(これがあとで叱られる原因に)。もうすごい盛り上がっていて、会場入って、おおお!とすごくワクワクしたのを覚えています。控え室に荷物を置かせてもらい、キーノートを聴きました。 Svetlana Isakovaさんに紹介してもらった、Inline classやimmutableListの話が非常に良く、早速どこに導入するべ?って検討していました。それとSvetlana Isakovaさんのスライドにまさか自分が出てくるとは思ってなかったのですごく嬉しかったです。

最近正直OSSで貢献できてないので、何かしなきゃ!と思いました。

ランチ

前日のツイートで集まった三人の方落ち合おうとしていたら、八木さんがランチ相手を探していたので、八木さんを引っ張っていき、去年と同じところでランチしました。

バックグランドがみんなバラバラだったのですが、去年同様結構盛り上がりました。 話の内容はKotlinの話はもちろん、Androidの話であったり、サーバサイドの話であったり、業務の話であったり、多岐に渡りました。 たった1時間しかなかったのが残念ですが、やっぱり初めての人とご飯行くの楽しいし、知ってる人がいても楽しい!という気づきがありました。 これは来年もKotlin Festがあるならぜひやりたい!

当日(午後)

午後のトークは自分の登壇が15:30からあると言うことであんまり聴いてないのですが、以下の二つを聴講しました。

  • Kotlin コルーチンを 理解しよう 2019
  • 公募によるLT大会

八木さんのトークはコルーチンの知識を最新版にアップデートしようと思いましたが、すんごくうまくスライド作っていて、発表内容も濃く、コードが読みやすく、途中で自分のスライドや発表内容直したくなりました。ちょっと自信を無くして、控え室に行った覚えがあります。

LTはどれも良かったです。途中どうしてもトイレにいきたくなってしまい、漏らして人生終わらすならここで行くしかないと、「静的解析ツール detekt で任意の条件で警告させる」の話途中で抜けてしまいました。lintの話は大好きだったのでめっちゃ悔しかったです。急いでトイレ行った後に戻ってきたら会場が爆笑していて、漏らさなくて良かったけど、トイレはトーク前に行こう!と言う小学生並の知見を得ました。動画に映ってる気がするので、まじで申し訳ないです。すいません。LTはめちゃくちゃよくて、どれも5分じゃなくてもっと長い時間で聴きたい!と感じました。

登壇

スライド

speakerdeck.com

GraphQLの話をする時、どこから話せば良いんだろう?と悩み、結局出来上がったのがKotlinの話をせずに1/3基本的なGraphQLの話をすると言う選択でした。 最初にGraphQLの経験を確認してみたのですが、思った以上に少なくて、この選択が間違ってなかったー!良かったーと話ながら思っていました。 GraphQLのデメリットの話は時間的に削りました。LTでGraphQLのN+1問題が辛いって話が出ていたので、そこで紹介してもらえたし、結果オーライかなーと。

今回意識したのがspeakerdeckではあんまり見えないのですが、スライド間のトランジションです。 GraphQLはデータの流れ、クエリの流れなどを理解することが重要だなと思っており、Magic Moveを駆使してそれを表現してみました。 聴いてくれた方があれがすごく良かったと反応をくれたのが本当に嬉しかったです。

余談ですが、Magic Moveを使う場合、閉じ括弧が消える問題があるのですが、これを解消するために、調べていたら結局Jakeさんに到達して、自分はようやく彼の5年前に追いついたのか・・・愕然としていました。(解消方法は下のツイートのスレッドに記述されていますが、透過率100%の文字を括弧の後ろに入れました。)

オープニングでたろうさんが盛り上げましょうみたいな話をしてくれたので、話を聴いてくれた人たちが結構トーク中に反応してくれて嬉しかったです。 スライド作った当時本当にコードしかなくて、これ絶対寝るわ。って思ったので、どうにかして、興味を失わず、理解してもらう方法を実施していたので、話ていて気持ち良かったです。聴いてくれた人たち本当にありがとうございました!

登壇後

Ask The Speakersで30分の休憩全部使って質問対応しました。 みんなかなり面白い質問をしてくれて自分まだまだGraphQLのこと知らないなーって思いました。

最初APIの開発辛いよねーって大げさな話を出したのですが、まさにあれば起こってるんです!ぜひ導入してみたい!と言う話を何人かにしてもらえたのがやっぱりこう言うのあるんだ。とびっくりしつつ、めっちゃ嬉しかったです。

ブース

ブースですが、朝ブースにいる知っている人たちを見つけて、挨拶をして、あとで来ます!と宣言して、Ask The Speakers後に向かいました。 しかし、自分のAsk The Speakersが終わる時間がブースの撤収開始時間らしく、ほぼほぼ回れませんでした。。。 家族がブースでもらえるノベルティが大好きで、Twitterを眺めていて、あれ良さそう!と自分の帰りをワクワクして待っていたようなのですが、ステッカーだけもらって帰って来た自分に対し、なぜもっと早く会場に行かなかったのか?とガチ目な説教をしてきました。次回以降しっかり早めに行きます。。。

各社のノベルティ、すごく工夫されていて -> 持って帰る -> 家族が喜ぶ -> その会社のプロダクトを使う と言う良い流れが私の家では出来ています。

懇親会

懇親会ですが、結構いろんな方と話せてすごく楽しかったです。 Svetlana Isakovaさんに登壇直前の時間にあとで話しかけるね!と宣言しており、immutableListの話を聴けて満足しました。

また初めての方が結構な数話しかけてくれたのが本当に嬉しかったです。自分が知ってる人に対しては話しかけることができるのですが、初めての方は紹介してもらうなりしないと遭遇出来ないです。 でも食事を盛っている時とか、「今話しかけても良いですか?」とか言ってもらえて本当に嬉しかったです。 ご飯食いたいけど、それ以上に話したいってのがあるので、どんどん話しかけてもらえるとありがたいなーと。 お子さんを連れて参加していたポールさんとそのお子さんとお話も出来たのも良かったです。自分もいつか子供連れて勉強会とか参加したいなーと。

まとめ

来年もあったら絶対参加したい!絶対また登壇したい!おー!!!


一人で馴染みの店で打ち上げ。めっちゃ美味かったー。

Yet another emoji support をリリースしました。

Yet another emoji supportという絵文字の入力をサポートするIntelliJプラグインをリリースしました。

f:id:shiraji:20190607004731g:plain
イメージとしてはこんな感じ

f:id:shiraji:20190607004809p:plain
Commitダイアログでも利用できます。

github.com

経緯

元々Emoji supportプラグインを公開していました。しかし、いくつかのissueで絵文字をコミットダイアログ以外のところでも挿入したいと言う要望を受けることが多くなりました。cmd+ctrl+spaceで入力できると何度も伝えていたのですが、なぜかみんなあんまり納得してくれませんでした。リリースから3年経過し、公式のサポートもまだないため、需要があるかさっぱりわからないですが、一旦作ってみるかということで作りました。

特徴

特徴としてはどの言語でもコメントでの入力をサポートしています。また自分の気づいたベースの言語に関してはStringの中での入力ができるようになっています。(GroovyとScalaが初期リリースでサポートされていないのは完全に失念していたためです。次のバージョンで対応予定です)

細かい点としてはKotlinのようにString内でコードを書ける場合、コードを書くことが可能な箇所ではCompletionが出ないようになっています。

val foo1 = "${:<caret>}" // この場合は出ない
val foo2 = ":<caret>${}" // この場合は出る

graphql-spring-boot-starterのExceptionハンドリングがめっちゃ便利になってた

Kotlinサーバサイド開発者のみなさん、graphql-javaでの開発の調子はどうでしょうか?

去年末にリリースされたバージョンのgraphql-spring-boot-starterのExceptionハンドリングがめっちゃ便利で感動したので、ブログに残しておきます。

想定読者

  • graphql-spring-boot-starter使って、GraphQLやってる人/これからやる人

はじめに

graphql-spring-boot-starterのバージョンが5.0.4の時、Resolver内で発生したExceptionは特に何も指定しない場合、全て Internal Server Error(s) while executing query と言うmessageを返していました。 例えば、AuthException のような自前で作成したExceptionが出た場合、レスポンスとしては違ったものを返したくなりますが、問答無用でInternal Server Error扱いです。(ちなみに最新版でも互換性を残すため、同じ挙動です)

    @Suppress("unused")
    fun diseases(icd: String): List<Disease> {
        if (icd.isEmpty()) throw IllegalArgumentException("icd must not be empty")
        return service.getDiseases(icd)
    }

f:id:shiraji:20190424022910p:plain
何だろうとInternal Server Error!

そこで、カスタマイズしたエラーを返すようにしたいのですが、探せど探せど良い方法が見つかりません。issueにこのドキュメント通りに書けばいけるぜ!と書かれているので、URLをクリックすると

        \          SORRY            /
         \                         /
          \    This page does     /
           ]   not exist yet.    [    ,'|
           ]                     [   /  |
           ]___               ___[ ,'   |
           ]  ]\             /[  [ |:   |
           ]  ] \           / [  [ |:   |
           ]  ]  ]         [  [  [ |:   |
           ]  ]  ]__     __[  [  [ |:   |
           ]  ]  ] ]\ _ /[ [  [  [ |:   |
           ]  ]  ] ] (#) [ [  [  [ :===='
           ]  ]  ]_].nHn.[_[  [  [
           ]  ]  ]  HHHHH. [  [  [
           ]  ] /   `HH("N  \ [  [
           ]__]/     HHH  "  \[__[
           ]         NNN         [
           ]         N/"         [
           ]         N H         [
          /          N            \
         /           q,            \
        /                           \

こんなページに飛ばされ、かなりイライラします。*1

でまぁ、色々調べていくと、Authエラーなどで全処理中断させたいであれば、 GraphQLException を実装すれば、一般的なランタイム時のExceptionとなり、エラーを返してくれると書いてあるので、試してみます。

    @Suppress("unused")
    fun diseases(icd: String): List<Disease> {
        if (icd.isEmpty()) throw GraphQLException("icd must not be empty")
        return service.getDiseases(icd)
    }

結果

f:id:shiraji:20190424023144p:plain
返してくれなかったよ・・・涙

このあたりで心折れます。

Spring BootでのExceptionハンドリング

話変わって、Spring Bootには結構便利なExceptionハンドラがあります。 以下のような感じで、各種Controller内で発生したExceptionに対して、一箇所でうまくシュッとやってくれます 😤

@RestControllerAdvice(basePackageClasses = [ExceptionHandlerAdvice::class])
class MyExceptionHandlerAdvice {

    @ExceptionHandler(TimeoutException::class)
    @ResponseStatus(HttpStatus.REQUEST_TIMEOUT)
    fun handle(exception: TimeoutException): ExceptionResource {
        log.error("caught an exception", exception)
        return ExceptionResource("タイムアウト")
    }

    @ExceptionHandler(WebExchangeBindException::class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    fun handle(exception: TimeoutException): ExceptionResource {
        log.error("caught an exception", exception)
        return ExceptionResource("なんか起こった")
    }

}

まぁあんまり詳しく書いても話が逸れるので、こんな感じのものがあるのだなー程度で良いです。

で、graphql-javaでもこんな感じで処理したい!と思う訳です。

時間が解決してくれた(=中の人達が頑張ってくれた)

それから数ヶ月が経ち、graphql-spring-boot-starterがメキメキ更新されていました。

現在の最新のバージョン(5.7.3)を使い、graphql.servlet.exception-handlers-enabledをtrueにすると以下のコードでもうまくハンドリングしてくれるようになります。*2

    @Suppress("unused")
    fun diseases(icd: String): List<Disease> {
        if (icd.isEmpty()) throw IllegalArgumentException("icd must not be empty")
        return service.getDiseases(icd)
    }

f:id:shiraji:20190424030032p:plain
IllegalArgumentExceptionですらうまくメッセージを返すように

ものすごく良くなりました。しかし一点typeがException名になってしまいます。 フロント側で IllegalArgumentException を処理してもらうで良いのですが、ちょっとダサい。GraphQLExceptionをthrowしたとしても、同じようにtypeが表示されてしまいます。

Spring BootのExceptionハンドリングのように特定のExceptionに対して、カスタマイズしたGraphQLErrorを表示したくなります。

そこで登場したのが、exception-handlers-enabledが導入されたタイミングでgraphql-spring-boot-starterが @ExceptionHandler によるExceptionのカスタマイズ機能です。実装方法としてはこんな感じのBeanやComponentをクラスを作るだけ!

@Component
class GraphQLExceptionHandler {
    @ExceptionHandler(IllegalArgumentException::class)
    fun handleSomeException(e: Throwable): GraphQLError {
        return GenericGraphQLError("Foo! ${e.message}")
    }
}

それで同じようにExceptionを発生させると

f:id:shiraji:20190424031759p:plain
メッセージやtypeを表示しないなどのカスタマイズが出来た!

これにより、エラーメッセージのカスタマイズやtypeなどを表示しないなどなどエラーハンドリングが容易に出来るようになりました。

実際のコード

実際にUbieで公開している https://github.com/ubie-inc/kotlin-graphql-sample に、動くコードをコミットしてあります。上記には記述してありませんが、graphql-java-toolsのバージョン上げも必要になりますので、ご注意してください。

github.com

*1:https://graphql-java.readthedocs.io/en/latest/https://www.graphql-java.com/documentation にリダイレクト機能なし+ドキュメント削除して移動したことが原因です

*2:5.3で導入され、5.4.1でバグfixされています。

Androidエンジニアからベンチャー企業でサーバーサイドエンジニアに転向して半年経って分かったこと

8/20入社だったので2/20でUbieに入社して半年になりました。つまりサーバサイドエンジニアに転向して半年経ちました。

以前の記事でこんなこと書いたので、続編を書いてみようと思います。

半年くらい働けば、きっと悪いところももっと見えてくるはずなので、来年落ち着いたらまた続編を書いていきたいと思います。

Ubie, incに入社しました。 - shiraji’s diary

今月のツイートを冷静に眺めてみるとそこまで自社に関してのツイートしていないし、恋は盲目状態から解放されているようなので、冷静に自分のことを分析してみようと思います。

サーバーサイドにキャリアチェンジしてどうだったか?

サーバサイドにキャリアチェンジしたのが正解だったかどうかに関してはまだわかっていません。これに関しては結論が当分出ないような気がしています。ただ、以前のエントリーにも書いてありますが、元々AndroidアプリもUIのことより通信だったり、パフォーマンスだったりを主に見ていたため、AOSPの辛さがなくのびのびKotlinを書けるという環境は本当に楽しいです。今後、多くのネイティブアプリエンジニア達がサーバサイドに目を向けるようになってきた時にサーバサイドKotlinというのは一つの可能性でもあるし、ガンガン発信していって、サーバサイドKotlinのプレゼンス高めていきたいという想いがあります。

新しいチャレンジ

新しいチャレンジとしてはGraphQLに手を出し始めたのは自分にとって大きな出来事でした。

shiraji.hatenablog.com

shiraji.hatenablog.com

GraphQLといえばGo、Rubyなどといった言語を使うのが主流な気がしますが、JVM言語でも可能性あるのでは?というところまで自分の中で良い印象を持っています。さらにここにKotlinならではの良さを追加出来ないか?と模索しているところです。

Androidアプリ開発と比較しての設計

設計に関しては、Androidアプリのように活発な動きはなく、特にAPIの作成の時などはシンプルな構成になります。ただし、Androidアプリでの経験が活きないか?と言われるとそれは間違っていて、Androidアプリで利用したDIやクリーンアーキテクチャなどは元々サーバサイドにあったものですし、そのまま利用することが出来ています。

開発環境

今まではAndroid Studioを使っていましたが、IntelliJ IDEAに乗り換えています。Android StudioIntelliJを両方使ったことある人であれば、わかると思いますが、特に使い勝手は変わらず、多くのサーバサイドKotlinサポート機能が乗っていて、そこの乗り換えコストはほぼ0です。(自分はIntelliJ IDEAでプラグインを開発していたという経験もあるので、生存バイアスかかってるかもしれませんが。。。)

さらにCoroutineやテストツール(JUnit5やmockkなど)など馴染みがあるツールをそのまま利用できる事もあり、サーバサイド辛いなーと感じることが少ないです。

サーバサイドエンジニアとしての課題

自分が今課題と感じているのが、自分自身、結構ネイティブアプリの開発に注力しすぎてしまったため、ネイティブアプリのライブラリなどの知識は深くなっていますが、昨今のウェブの開発スタイルにまだ馴染めていません。UbieではGCPを主に使っていますが、GCPにどんな機能があるのかを完全に把握しておらず、実装しようとして、あれ?その機能GCPにあるのでは?というツッコミを受けたことがあります。その機能がどういうものなのか?などの把握はそこまで時間がかからないのですが、自分の引き出しの少なさにちょっとがっかりしています。

サーバサイドの進化はネイティブ開発に比べ遅い!と勝手に思って7,8年前までのサーバサイド開発のスタンスでいたのですが、これは完全に間違いでした。

Androidアプリエンジニアとしての不安

Androidアプリ開発の一線から退いて半年経ち、一番の不安は、最新のライブラリのキャッチアップが出来ないことです。例えば、JetPackの存在は知っていますし、コードはある程度眺めています。しかし、仕事でJetPackを使っていないですし、経験がありません。今年のGoogle IOでまた新しいものが発表された時、それに対して何かしら自分がアクションを起こせるかどうかは正直不明です。そのため、もしAndroidアプリエンジニアとしてカムバックしなくてはならない時、何かしらキャッチアップ期間がないと厳しそうだなーという感じています。

実際、今サーバサイドエンジニアにカムバックしたといえばカムバックした訳で、このキャッチアップに時間を使っているというのも不安です。半年経った今でもまだサーバサイドエンジニアですと胸張って言えないような感じなので、キャッチアップって結構時間かかるなーという印象を持っています。

ベンチャー企業に入ってどうだったか?

今までいくつかの企業で働いていて、上場してない企業としてはUbieは2社目です。それ以外の会社は全て上場していて、多くのユーザーを抱えている企業でした。1社目は10人くらいで、今回は現在20人くらいなのでほぼ変わらない規模です。こういう会社に入ると感じるのは自分の稼働が会社へダイレクトに良くも悪くも影響を与える事です。変なバグを出してしまったりすれば会社は潰れるかもしれませんし、逆に素晴らしい機能を出せば一気に会社が大きくなる可能性があります。自分が会社を動かしているかも?という錯覚すら覚えて喜べます。1社目で感じていたのですが、こういう感覚が好きなエンジニアには小さい会社ありだなーと改めて思いました。

f:id:shiraji:20181220164930j:plain
アイキャッチ画像がなかったから、無駄に、自分のデスクのマスコットのアー写置いておく。

ルール

新しい会社にはよくあることですが、ルールが決まっていないかったり、そもそもなかったりします。必要であれば社員みんなで議論して、即ルールを制定しています。

こういうことは小さな会社だから出来る自由さ、フットワークの軽さがあって、すごくいいなーと感じています。

働き方

働き方は今までよりワークライフバランスを特に意識するようになりました。これはリモートワークがいつでも自由に出来る状況*1であることが起因しているのですが、やろうと思えば、深夜でも早朝でも土日でもプライベートの時間を削って仕事が出来る状況になっています。 自分のプライベートのGitHubアカウントを会社でも使っているので、GitHubの通知を見ようとすると会社の通知とOSSの通知を同時に受け取ってしまえます。さらに言うと、自分の会社の出社時間が10:00-17:30でだいたい多くの人より早く帰っており、家で足りない稼働分(30分)働いています。そのためそのまま流れで気づいたら仕事してたみたいな状況に陥りがちです。会社の今のフェーズはできるだけ多くのリソースを割いて、サービスをどんどん良くしていくというのはわかっています。しかし今まだ設立1年半のこのタイミングでエンジニアがいっぱい残業してしまうと今後入ってくる人もそういうのを会社は期待してしまうし、それは健全ではないと思っているので、自分1人だけでもワークライフバランスを特に意識しています。

タスク

任されているタスクは結構自分から手を挙げたものが多いです。

  • サーバサイドKotlinの実装
  • DBテーブルの設計・実装
  • 協力会社との連携処理の設計・実装
  • SREの細かいタスクのサポート
  • bot作成(これはほぼ遊びか?)

今フロントエンジニアの質がものすごく充実しているように見えます。結構勉強出来そうな環境です。しかし、今の自分がフロントで足引っ張るより、サーバサイドや人が足りていないSREで足引っ張った方が会社のためになるでしょという判断をしたため、SREエンジニアの修行させてもらっています。手取り足取り @sakajunquality から知見吸えているのですごく良い判断したなーって思っています。

時間の使い方

これまでの会社と一番違う部分は実は時間の使い方なんじゃないかと思っています。今までの会社ではリーダーだったり、外部の方とのやりとりだったり、雑多な管理だったり、採用だったりと、そこまでまとまったの時間を開発に割いていませんでした。(これだけ読むとダメじゃんー!って思われるかもしれませんが、自分はこれはこれで実は結構好きだし、楽しかったです。)

今の会社では毎週以下のような時間割でやっています。

  • 会議(3時間15分 *2 )
  • その他、定期的ではない会議や採用周り、週平均2時間くらい
  • 残り週30時間以上は開発

この定期的な会議の多くは出社推奨日の水曜にまとめています。そのため、結構まとまった時間開発することが出来ています。ただ、これでも自分の会社の滞在時間の制限があるため、週1以上は必ずリモートで仕事をし、より長く開発に時間を割けるように工夫しています。

初めての経験

Ubieに入って初めての経験がいくつかありました。

OKR/KPT

スクラムなどは経験あったのですが、今まで業務でOKRやKPTを実際にやったことがありませんでした。OKRは今期から本格的に実施することになり、会社から本を買ってもらい、みんなで勉強して実施するようになりました。KPTは良かったことを褒め合う機会と問題の共有・対処の検討などをしっかりやれるのが気に入ってます。

アウトプットする人が多い

今まで自分より登壇する回数が多い同僚と働いたことがなかったです。Ubieでは社外へのアウトプットを推奨しており、エンジニアはもちろんのこと、デザイナーや医師、Bizもアウトプットする機会があればどんどんアウトプットしています。これがすごく刺激的で、自分ももっとアウトプットしたい!という気持ちが湧いてきます。

名前

これは入社時からだけど、会社で初めて「しらじ」って呼ばれてる。呼ばれすぎてて、社外の方と話すときに、自分のことを本名で呼ばれたりするとドキっとするようになってしまった。。。

引っ越し

先日Ubieは引っ越しをしました。新しい場所は三越前駅徒歩10秒です。

goo.gl

今までも席替えやビルの部屋が変わるなどは毎年1,2回のペースで経験してましたが、オフィスの場所が変わる引っ越しは初めての経験でした。新しい環境で働くのはいつもワクワクなので、引っ越してもそこまで変わらないだろうなーって思ったのですが、引っ越して駅から近くなって、オフィスも広くなって、会社の成長をモロに実感出来たのがすごく嬉しかったです。ベンチャー企業の醍醐味だなーこれ。と感じています。このオフィスも2年以内に引っ越す予定なので、次はもっと大きな場所で働けるようにがんばろー!って気分になれました。

最後に

Androidエンジニアからのキャリアチェンジですが、SREにも手を出してますし、今のところうまく進んでいる気がします。会社の成長を感じられるのが本当に嬉しい日々です。

さて、こんなUbieですが、引き続き、いろんな職種を募集しています。

speakerdeck.com

随時オフィス見学やUbie Dayなど社外の方を呼んで来てもらうようなイベントもやっていますので、興味あれば、TwitterでメンションやDM下さい。

*1:最大週2で、出社推奨日もあります

*2:1時間チーム内KPT, 30分全体KPT, 30分採用定例, 1時間エンジニア定例, 15分業務委託の方と1on1

DroidKaigi2019に参加しました

DroidKaigi2019に参加することが出来たので、感想を書いておきます。

聴講したセッション

1日目

  • ウェルカムトーク
  • マルチモジュールなプロジェクトでテストはどう変わる?
  • マルチモジュールプロジェクトでのDagger2を用いたDependency Injection
  • Server-side Kotlin for Frontend: 複雑なAndroidアプリ開発に対するアプローチ
  • PWAでここまで出来る
  • Exploring the Android Transform API
  • Fireside chat && 懇親会

2日目

  • build.gradle.ktsに移行しよう
  • 夕飯

ウェルカムトーク

動画カッコ良かった。あとで納品されたのが当日9:30頃でめっちゃヒヤヒヤしたという話をtnjさんがしてて、ウケた。

それと、mhidakaさんのマイクがなんか変な音がしてて、聴きづらく、少し我慢してたのですが、誰も反応してないし、意を決してツイートしたら即対応してもらえた。(実際は自分のツイート起因なのかは不明だけど、嬉しかったので、そういうことにしておこうw)

マルチモジュールなプロジェクトでテストはどう変わる?

登壇者のテストが好きだというのがにじみ出ているようなトークでした。本当にテスト好きなんだなこの人!ってワクワクして聴かせてもらいました。 内容としては、DeNAさんのものなのかわからなかったですが、テストの方針やモジュールをどのようにテストするのか?とPITの紹介という感じでした。 わかりやすく噛み砕いてくれて、かなり参考になりました。スライドがシンプルで良かったです。

前半部分の方針の説明だったのですが、もう少し具体例が欲しかったかなと思いました。 方針の説明だから仕方ないのですが、それでもコードなどを示しつつ、方針と噛み合わせてくれたらさらに深く理解出来たと思います。 PITの説明に入ったら、具体的になって、その内容の面白さに会場がすごく盛り上がっていた印象を受けました。あれは本当に良かった。

マルチモジュールプロジェクトでのDagger2を用いたDependency Injection

去年に引き続き、kgmyshin さんのマルチモジュールのお話。 去年マルチモジュールの初歩的な話をしてもらい、今回具体的な実行編って感じの二部構成!って感じで勝手に感動してました。 スライドがすごく特徴的で、うまく手書きと図を使われており、流石だー!と感じました。

また、概要説明->実コード->概要説明->実コードと本当に素晴らしい流れで、めちゃめちゃわかりやすかったです。 いやーやっぱkgmyさんすごいなーと終わった時に改めて思いました。

Server-side Kotlin for Frontend: 複雑なAndroidアプリ開発に対するアプローチ

マイクロサービスを自社で導入しており、今後拡大した時にどうなるのか?BFFはどういう助けになるのか?が知りたくて聴講しました。 FiNCさんの過去の話からBFF採用するまでなどのお話でした。辛い辛い辛いーそうだよねそうだよね!という感じで結構感情移入しちゃって聴けました。 これは完全に自分の責任なのですが、遅れて入ってきたため、後ろの席で聴いたこと+登壇直前にツイートしてもらったスライド公開が残念ながら出来ていなかったこと+スライドの文字が多かったこと と不運が重なってしまい、スライドをめくった時にスライドを読むことに注力せざるを得ず、話を聞き逃すことが若干ありました。。。 なので、登壇後に直接いくつか質問させてもらいました。丁寧に回答頂き、なるほどーって結構な回数言わせてもらいました。(今スライド見返すと回答が書いてあったので完全にアホな質問ばかりだったかもしれません。。。)

FiNCさんはFin Techってネタは爆笑しました。(FiNCさんはヘルス事業の会社です。)

PWAでここまで出来る

自社が、PWAにベットしているので、あんまり説明も読まずにタイトルだけで聴講決めました。 今年のDroidKaigiで一番バズったのでは?と思う誤発注のDiverseさん所属の方の登壇でした。 DiverseさんがAndroidのFlutterエンジニア募集してると聴いておー!Flutterここまできたかーと驚きました。

PWAの基本的な紹介があり、その後TikTokさんに似たPWAサイトを作ると言う話でした。 PWAのGoogle Playでの公開方法の説明は実は初めて知って、おおおお!!!って驚きがありました。 作ってるものは本当に良かったし、話の内容もすんなり入ってきたし、面白いなーって聴けたのですが、一つだけ悲しいこと言っちゃうとコードの文字が小さくて全然読めなかった・・・。一つ前の時間で質問していて、席が後ろになったのが敗因でした。。。

ちなみに次の日に自分が同じ部屋で登壇するということもあり、参考にさせてもらいました。

実はこの登壇者の SAMUKEI さんとは2日目にホールで自分の登壇の質問待ちでボケーっと座っていたら、見つけてもらい、話しかけてもらえました。 最初赤髪の人と目が合ったー!こっち近づいてくるー!やばいー!!!とちょっとドキドキしたのですが、話してみるとすごく気さくな方で話やすく、楽しかったです。話終わった後に、あれ?そういえばあの人PWAの登壇者だったじゃん。って思い出して、あーPWAの話もっとすれば良かったと後悔しました。またどこかでお話しさせてください。

DroidKaigi2019ではDiverseさん面白い人多いと言う印象になりました。きっと来年はmini usb -> type cの誤発注してくれるでしょう!

Exploring the Android Transform API

これに関して言うと、自分にとって今年のDroidKaigiで一番楽しかったです。あまりに楽しすぎて、感想なんて要らない、みんなとにかくこのトークの動画を観るんだ!です。 簡単に説明するとAndroidでは使えないJava9のメソッド List.of をTransform APIで作り、Androidで動かしてしまおうと言うハッキーなお話です。まじで動くところまでライブコーディングしてます。動画が待ち遠しい。

Understanding Kotlin Coroutines: コルーチンで進化するアプリケーション開発

次に mhidaka さんの 「Understanding Kotlin Coroutines: コルーチンで進化するアプリケーション開発」を聴こうとしたのですが、早めに行ったと思ったのに、立ち見になっており、立ち見できる体力なかったので、泣く泣く諦めました。mhidakaさん人気すぎるんだよ。。。

Fireside chat && 懇親会

Fireside chatを聞こう早めに乗り込んだのですが、ちょっと遠く、声が聞こえませんでした。なので、会場入ってすぐに無理して聴くのを諦め、近くにいた方達と話していました。あの会場でのFireside chatは厳しいと思います。

懇親会はある程度知ってる方と話した後、新規の方との交流開拓のため、結構ぷらぷら歩いていました。

ただ、歩いてる時に話しかけられることはやっぱりない。
↓
テーブルに止まると話しかけてもらえる。
↓
でもテーブルに止まるには何か止まる理由が必要。
↓
テーブルに皿なら置ける
↓
食事・デザート・飲み物を持ちまくる。

ということでかなり食べてしまったような気がします。。。自分から話しかけるの無理なので、どうにか出来ないものか・・・。初めての人ともいっぱい話したいんだ。おかしな性格だ。

この懇親会でPixivの方にAndroidの勉強になるお話をしてくれたら、扇子くれるというイベント?やってました。こういうの話しかけるきっかけになるので良いですね!

inside.pixiv.blog

食事で並んでいたら見かけたので、「Find Pull Requestプラグインを作りました。」と言ったら、ポカーンとされて、完全に滑ってしまったわ。辛い。ってなったのだけど、別のPixivの方が「お世話になってます。」って言ってくれて扇子出してもらいました。めっちゃ嬉しかったです。

ステッカー以外のノベルティ特に反応しない息子くんもこれは気に入ったようで、返してくれません

f:id:shiraji:20190209121332j:plain
自分の登壇のMVP

Pixivの方に伺ったのですが、この扇子、Droidくんが入っているのですが、Googleさんに権利関係で連絡したとのことで、Pixivさんやっぱりサービス特性上、著作権周りもしっかりされているんだなーと感心しました。

build.gradle.ktsに移行しよう

二日目は登壇があり、自分のセッションより前のセッションは何も聴かず、自分の登壇後はすんごい倦怠感に襲われ、セッション聴くのを諦め控え室で引きこもってました。 体力が回復しつつあったので、去年に続き、tnj さんのgradleの話を聴きました。 build.gradle.ktsへの移行方法をプロジェクト作り、一つずつ手順を教えてくれました。 また、スライドには置換で活躍する正規表現も逐次記述しており、これがあれば簡単にbuild.gradle.ktsに移行できそうと言う印象を受けました。 こう言うビルドの話大好物なので、本当に楽しかったです。

2日目、控え室でtnjさんを見つけて、Android Studio 3.3.1当日リリースの被害を受けたということで記念に写真撮ってもらいました。

特に登壇の影響なくて良かった、いや良くなかった。バグが直ってないとtnjさんが混乱してる姿が面白すぎました。

夕飯

控え室でのんびりしてたら、gfxさんがご飯どうですか?って誘ってくれました。それなら!とこの会に興味ありそうな方にも声かけて、最終的に6人でご飯食べに行かせてもらいました。結構色々な話が出来て、本当に楽しかったです。

あの中で圧倒的に自分のスキルが一番低かっただろうなーって思い知ったので、もっと技術磨かなきゃって感じでした。


さて、ここからは話変わって、自分の登壇の話になります。

登壇

今回は2日目の14:00~でした。登壇の話を書く前にCfSの話から書こうと思います。

CfS

DroidKaigiのCfSがオープンになったということで、募集要項を確認しました。

droidkaigi.jp

なんか色々カテゴリがありますが、一番重要であろう点はここかな?と理解しました。

応募に当たって以下の3点を満たしていると採択されやすくなります。

Android specific: Android 固有であること
Expertise: よく知られている情報ではなく、専門性があること
Innovation: いままでに可能でなかったことを可能にしていること、革新性があること

この三つを満たしている物をCfSに書けば通るだろうと。

  • JetPackを本番で使ったことがなく、最新のAndroid開発周りでExpertiseとInnovationを満たすのは難しそう。
  • Kotlinはもう当たり前なのでチャンスあるとしたら、Coroutineだろうけど、自分より専門性高い人が多い分野だし、競合も多そう。
  • そうなるとAndroid Studioプラグイン開発かなー?と思ったけど、これは以前NGだったし、どこのカンファレンスでも需要がないのか今まで一度も通ったことがない。

今回やっぱり無理かなーと諦めていたら、同僚がJetBrainsのIDE使っていて、あれ?この設定使ってないの?ということが偶然あって、お?そういえば普段使われていないようなAndroid Studioの設定発掘したら面白いかも?とひらめきました。

そこからちょっとPreferencesを上から全部見ていって、設定を変えることにより、どうなるのか?を調べていきました。 そしたら、知っているもの含め、10個くらい面白そうな設定が出てきたので、一人で語りながら設定変えて実演してみたら、30分くらいに収まったので、うし、これでいくか!とCfS書きました。

CfSの書き方は特に奇抜なことはせずに全部書き出しました。

2014年末からAndroid Studio v1.0.0が出てから、ほとんどの方がAndroid Studioを使ってAndroidアプリの開発をしていると思います。
IntellijをベースにしたAndroid Studioでは非常に多くの機能が存在しています。しかしあまりにも多いため、埋もれてしまっている便利な機能があるのではないのでしょうか?
このセッションでは、Android Studioの隠れた便利な機能を紹介して、Android Studioを使った開発をより快適に出来るようにお手伝いしたいと思います。

以下の知識がある方を想定しています。
* Android StudioでAndroidアプリの開発をしたことがある
* Android Studioの設定をあまり変えたことがない
* 複数人での開発を主にしている
* セッション中にすごいと思ったら「おー!」って言ってくれる

このセッションでは以下の設定の話をする想定です。独断と偏見で大半の方が触らないであろうと思った設定を中心に説明します。
* 自分専用のアクションリストを作ってみる
* !=をカッコ良く
* 通知周り
* File Color
* Kotlinのファイルフォーマット忘れ防止
* 急に別の言語書きたくなった時のストレス発散方法
* JSON書きやすくする
* Run Configurationや.ideaの共有
* Layout Editor
* Pluginのインストールの強制

しっかり話す内容全部書き出したので、当日の齟齬は無かったはず。

これでCfS通らなかったら、Ubie, incに入社しました。 - shiraji’s diaryにも書いてあるとおり、Android開発から遠ざかっていますし、そろそろDroidKaigi卒業かなとも思ってました。その後、CfS通過連絡を受けて、まだまだDroidKaigiは自分を必要としてくれてたー!って結構喜びました。

登壇前

登壇前に、音声が出るのか不安だったため、運営の方たちに確認したところ、色々調整してもらい、ランチ時間にRoom1を使わせてもらえることになりました。 あの時間にRoom1にいた人たちは「なんだこいつ?」って感じだったと思います。申し訳なかったです。ランチ中にいきなり現れて、息子の動画とAndroid Studio喋らせてるヤツいたらそりゃそうなりますわ。。。

登壇時

twitter.com

意識していた「ライブ感」が本当にうまくできるのか?がすごく心配で、それが緊張を引き起こしてました。本当にみんな「おー!」って言ってくれるかな?って。音声チェックの時のように何こいつ?みたいな反応にならないかな?って。でも運営の人たちが緊張をほぐしてくれたので、だんだん調子が出てきました。

Macを見ずに俺を見ろ

この発言みんな笑ってくれたのが本当に助かりました。これで完璧に吹っ切れることが出来たと思います。きっと「おー!」の練習しっかりやってくれると。

ただMac見なくていいとは言いましたけど、まさかその時間でOS更新しようとするツワモノが現れるとは想像してませんでした。面白すぎる。DLは家でしてきたんですよね?

「おー!」の練習

そして、本番。すっごく盛り上がってくれました。やはりかわいいは正義だ。

その後、自己紹介中に「おー!」って言われたのは全く想定してなくて面白かったです。もうこの時には緊張なんて全くなく、全力で楽しんでいました。いい雰囲気でした。

Android Studioがしゃべった!

この辺、ライブ感満載で最高です。

Kotlinのスタイル設定

Kotlin Repositoryがこれを導入していたので、この設定は知っていたんです。でもこれが盛り上がるってことはみんなKotlinのコントリビュート環境整備してないってことなので実は寂しい!!!

コンディション設定してたのに間違って消しちゃうやつ!

この設定見つけた時すごく興奮した覚えがあります。というかこれ本当にデフォルトにしてほしい!

Inject Language

Inject Language自体が理解するの難しい機能で、それを説明して、その特定の不便さを説明して、それを解消する設定の説明っていう周りくどい感じだったんですよね。。。それを takahirom さん的確に説明してくれていて、さすがー!って思いました。

Prefer XML editor

推し

Notification出過ぎ

再起動中祈ったのに、結局いっぱい出てくれちゃって、あー!もー!!!って感じでした。練習ではもう一回再起動したりしてたのですが、なんか会場盛り上がっちゃったから、このままでいいかーって感じで流しちゃいましたwライブって感じ。

ツイートしてる暇がなかった

狙い通りです!

予約投稿

Twitterへの予約投稿は身内?であるたろうさんが反応してくれてました。本当にテレビの副音声みたいな機能に出来たらなーって思ってたので、嬉しい。

副音声ツイートは SocialDog さんを使わせてもらいました。TweetDeckで当初やる予定だったのですが、投稿予定だったツイートを確認する術がわからなかったため、選定出来ませんでした。

Room1がトレンド入り

登壇直後にハッシュタグ #Room1 がトレンド入りをしたと連絡もらいました。記念にスクショ撮っておきました。

f:id:shiraji:20190210042632p:plain

トレンドのロジックを全く理解していないのですが、Room1はそもそも各時間一番人が入るし、直前があのMotionLayoutのお話だし、いまいち何かを達成した感がないです。(そもそもTwitterじゃなくて俺を見てくれ!って話だったわけで・・・)

入れなかった方がいた・・・

開始直前まであのRoom1が満員になるなんて想像してなかったです。1部屋に入っていい人数って法律で決まっていると思うので、運営の方たちも自分もどうしようもできないので、ごめんなさい!としか言えないです。希望者全員に聴いて欲しかった。ライブ感をものすごく押し出していたので、furusinさんや他にもし会場入れなかった人がいらっしゃったなら、配慮が足りてなかったかもしれないです。本当に申し訳ないです。。。

登壇後

登壇後、良く見るすごい人たちが集まってきて「どうやって設定共有するの?」という質問を受けました。みんな同じ疑問を持っていたようです。

話を登壇中に戻すと、当初全ての説明が終わっても5分残っていたら、11個目の説明をしようと考えていました。10個目の説明の「Required Plugins」を話始めたタイミングで残り5分を切っており、さらにNotificationが出過ぎハプニングのため、会場が盛り上がってました。そんな良い感じの雰囲気のまま「Required Plugins」の説明は残り3分のところで終わりました。最後に感謝の言葉を言うのは30秒もあればできるので、強引に続けてもよかったのですが、練習不足であるのが明らかで、せっかく盛り上がったのに、話を延長して、残念な終わり方は嫌だなー。終わりよければ全て良しだよなーって逃げの気持ちが先行してしまい、そこで「ありがとうございました」と締めてしまいました。

が、やはりあの出来る人たちには見逃してもらえない感じでした。そこで、.ideaの設定共有の話をしたのですが、仕組み自体はただのファイルをgitで管理しているという簡単なものなので、1分もかからずみんな納得してくれて「あーこんな簡単ならやれば良かった・・・完全にチキンだったー」と自己嫌悪でした。

オフィスアワー

登壇後の質問で囲まれた時に運営の方に「やっぱりオフィスアワーやりますか?」と言われました。これは自分の聞き間違えだったかもしれないです。 そこで自分は(あ、自分はオフィスアワーなしだったんだ。)と勘違いしてしまい、質問対応後、そのまま控え室に戻りました。

そしたら、どなたかが、オフィスアワーで待ってくれてた様で、それを知った時には次のセッションが始まっていました。

そこで運営の方が色々動き回ってくれて、こんなツイートをしてくれました。

諸々対応して頂き、ありがとうございました!今後もいつでも回答しますし、DMも空いてますので、何か質問あれば今からでもしてください。

まとめ

とにかく楽しかったです。

自分は年2回くらいしかこういう大きなイベントには参加しないので、運営の人や他の参加者の方達よりゆるいスケジュールで当日過ごしました。 しかし、二日後のいまだに体が本調子に戻らなくて、ちょっとまずいなーって感じです。もうちょっと外に行こうか・・・?

Android開発者ではないので、次回のDroidKaigiでCfS突破できるようなネタが探せるのか?が課題ですが、来年も登壇出来たらなーって考えています。おもしろ登壇枠があればきっと大丈夫だと思うのですが・・・

運営の方たちの細かな気配りがいっぱいありました。色々対応して頂き、ありがとうございました。

そして、最後に、自分の登壇を聴いて下さった方たち、当日「おー!」と盛り上がってくれて本当に本当に本当に話しやすかったです。すっごく気持ち良かったし、楽しかったです。ありがとうございました!!!

Android Studio設定見直してみませんか? -詳細-

このブログはDroidKaigi 2019Android Studio設定見直してみませんか? の詳細です。 せっかく聴いてくれる方がメモを取ってて話を聴き逃してもらいたくないためのエントリーです。

登壇中何らかの問題が発生した時の対策でもあります。

前提

  • 設定の遷移の区分けはJetBrainsの公式と同じで「 | 」です。「Preferences | Keymap」という記述の場合、Preferencesの中にあるKeymapというメニューを表しています。
  • Macを使っている前提で話が書いてあります。
  • Android Studio 3.1から3.3.1での動作確認はしています。

Quick Lists

リファクタ、Surrend With、右クリックなどをすると出てくるポップアップがあると思います。

f:id:shiraji:20190202145813p:plain:w300 f:id:shiraji:20190202145726p:plain:w300
いろんなポップアップがあります

これ、実は自分専用のポップアップを作ることができます。

Preferences | Appearance & Behavior | Quick Lists

と遷移するとQuick Listsを作成する画面が出てきます。

f:id:shiraji:20190202150153p:plain
Quick Listsの設定画面

ここの「+」をクリックし、「Display name」にはわかりやすいものを設定し、ポップアップに表示したいアクションを追加します。

f:id:shiraji:20190202150414p:plain
shiraji quick listsというQuick Listsを作ってみました

「Find Actions」で「Display name」に入力した値を選択すると、自分でカスタマイズしたポップアップが表示されるようになります。

f:id:shiraji:20190202150617p:plain
Find Actionsに表示される

f:id:shiraji:20190202214450p:plain
自分専用のポップアップが!

このQuick ListsはKeymapを設定することも出来て、便利です。

f:id:shiraji:20190202150740p:plain
keymapも設定できる

Font ligatures

!=, ->, ==ってITエンジニアなら読むことは出来ると思うのですが、!=は≠と表示される方がカッコイイです!(主観です)Android Studioではこの表示をサポートしています。

Preferences | Editor | Font

Enable font ligaturesにチェックを入れ、Font ligaturesに対応しているフォントに変えます。

f:id:shiraji:20190202151148p:plain
Fontはデフォルトで入っていてFont ligaturesに対応しているFira Codeを選択

そうすると、コードがこんな感じに表示されるようになります。

f:id:shiraji:20190202151032p:plain:w300 f:id:shiraji:20190202151234p:plain:w300
左が変更前、右が変更後

Notification

右下や右上に出てくるポップアップです。

f:id:shiraji:20190202151703p:plain
Power Save ModeをONにすると出てくるポップアップ

このポップアップですが、すぐ消えちゃったり、何度も出てきてイライラさせたりしてくれます。 全てのポップアップにはIDが振られており、Notificationの設定で表示方法を変えることができます。これは3rdパーティのプラグインも含まれます。

f:id:shiraji:20190202151917p:plain
Gradle Syncが終わったらポップアップを表示させるようにしてみる

今回紹介したいのはこの設定ではなく、どのNotificationでも使われていない、「Read aloud」という設定です。

f:id:shiraji:20190202152300p:plain
どの設定もOFFになっている

Gradle Syncの設定の「Read aloud」を選択して、Gradle Syncをしたらどうなるでしょう? Notificationの内容をAndroid Studioが大きな声で何秒かかったのかを伝えてくれます!(この渾身のネタが文字でしか伝えられない悲しさ・・・)

ちなみに当日は、「おおおお!」とAndroid Studioさんに言ってもらうためのプラグインを使い、褒めてもらいました。

github.com

File Color

File Colorはデフォルトで利用されているので、結構みんな知らないうちに使っている機能だと思います。Project Viewにあるテストコードの背景が黄緑になっています。これがFile Colorです。

f:id:shiraji:20190202184757p:plain
背景が黄緑色になっている

f:id:shiraji:20190202184859p:plain
タブも色が変わる

File Colorは便利な利用方法があります。

Preferences | Appearance & Behavior | File Colors

f:id:shiraji:20190202210717p:plain

上の方のWindowにある、プラスボタンをクリックします。

「Scope」を「Production」として、「Color」を「Blue」としてみます。そうすると、「Run」ボタンを押して、アプリを起動する時に利用されるソースコードが青くハイライトされるようになります。

f:id:shiraji:20190202210853p:plain
青くハイライトされる

Build Variantを変えても即反映されます。

f:id:shiraji:20190202211137p:plain
Build VariantをpremiumReleaseにしたら、debugのソースのハイライトが消え、premiumのソースがハイライトされた

コードフォーマット

コードフォーマットにはいろんな方法が提供されています。

昔よく話に上がっていたのは、reformat code/organize importsなどを保存時に実行するマクロを組むとか、Eclipseのデフォルト機能から作られたであろう、Save Actions - Plugins | JetBrainsというプラグインを導入する、Commitダイアログにあるreformat code/organize importsなどにチェックして、Commitする。

f:id:shiraji:20190202212158p:plain
Commitダイアログのコードフォーマットの設定

ここで紹介するのは、コードを書いているときに、コードフォーマット漏れしているかを確認する方法です。

Preferences | Editor | Inspections | Kotlin | Style Issues

KotlinのInspectionの中に「File is not formatted according to project」という設定があります。これを有効にして、「Severity」を「Error」とします。

f:id:shiraji:20190202212545p:plain

これでプロジェクトのコードフォーマット設定に違反したコードを書くと文法エラーのような表示なります。

f:id:shiraji:20190202212658p:plain
コードフォーマットされていないとエラー表示になる

この赤線のところで、「Option(Alt) + Enter」をすると、「Reformat File」という選択肢が出るようになります。

f:id:shiraji:20190202212737p:plain
Reformat Fileという選択肢が出る

そこで「Reformat File」を選択すると、フォーマットされるようになります。

f:id:shiraji:20190202213134g:plain
簡単にコードフォーマットできる

これを利用すれば、コーディング中にフォーマットされているかどうかの確認が可能です。Android Studio上でエラー表示になっているだけで、ビルドは問題なく出来ます。

余談ですが、特定の箇所をCode Formatしたくない場合もあると思います。そう言う場合は

Preferences | Editor | Code Style

「Enable formatter markers in comments」を有効にし、「@formatter:off」と「@formatter:on」で括れば、フォーマットエラー表記もされないようになりますし、「Reformat File」しても無視されます。

f:id:shiraji:20190202214019p:plain
コードフォーマット対象にはならない

Breakpointsの削除

Breakpointsはデバッグ時に必須なものです。Breakpointsを特定の条件下のみ発動することも可能です。Breakpointを右クリックし、「Condition」を入力すればその「Condition」がtrueの時のみBreakpointで止まります。

f:id:shiraji:20190203013509p:plain
Breakpointに条件を追加する

で、このBreakpoint、作るときも削除するときも簡単で、クリックしたら出来ちゃいます。

f:id:shiraji:20190203013747g:plain
ワンクリックで簡単すぎる削除・・・

結構複雑な条件を設定したにも関わらず、誤ってワンクリックで消してしまい、またその条件を入力しなくてはならなくなった経験ありませんか?筆者は首がもげるくらいあります。

この問題への対処方法があります。

Preferences | Build, Execution, Deployment | Debugger

「Remove breakpoint」のところにある、「Confirm removal of conditional or logging breakpoints」を有効にしてみてください。

そうすると、条件付きのBreakpointをクリックすると、削除するか確認ダイアログが出現するようになります。

f:id:shiraji:20190203014225p:plain
削除するか確認ダイアログ

Inject Languages

Inject Languageと言う機能は生のStringに対して、JSONYAMLなどの言語に対するサポートができるようになる機能です。

対象のStringにカーソルを合わせ、「Option (Alt) + Enter」を押し、「Inject Language or reference」を選択します。その後、そのStringの言語を指定したら、その言語のサポートを受けられるようになります。

f:id:shiraji:20190203015402p:plain
同じ文字列なのに、コードハイライトが有効になっている

また、ここではJSONを利用しているため、「Edit JSON Fragment」と言う機能も利用でき、それを利用すると、別WindowでJSONを入力したら、エスケープなどを良しなにやってくれるようになります。

f:id:shiraji:20190203015606p:plain
下のWindowで編集したら上の文字列に反映される

この機能は非常に便利なのですが、チームで共有するためには、@language("JSON")//language=jsonなどを記述しなくてはなりません。この記述は「Inject Language or reference」を選択したタイミングですぐに再度「Option (Alt) + Enter」を押せば補完してもらえるのですが、忘れがちです。

f:id:shiraji:20190203020224p:plain
アノテーションをつけるかを聞かれる。別のアクションをしたら消えてしまう!

この問題を解消する機能があります。

Preferences | Editor | Language Injections | Advanced

この設定画面の一番下にある「Add @Launguage annotation or comment if needed」を有効にします。その後、もう一度「Inject Language or reference」を選択すると、@language("JSON")//language=jsonを最初から補完してくれるようになります。

Layout Editor

Android開発者なら誰もがお世話になるだろうLayout Editorの設定の紹介です。

f:id:shiraji:20190203135101p:plain

このLayout Editorは設定がいっぱいあって、なかなか面白い機能ではあるのですが、今回紹介するのはこの画面の設定ではなく、Preferecesの方の設定を変えてみます。

Preferences | Editor | Layout Editor

f:id:shiraji:20190203135321p:plain

この三つの設定のうち、一番上にある、「Prefer XML editor」という設定。有効にしてみて、もう一度Layout Editorを開いてみます。

f:id:shiraji:20190203135434p:plain
Prefer XML editorを有効にして、開き直しても特に見た目の違いが見えない。。。

よーく見てみます。

f:id:shiraji:20190203135607p:plain
本当に違いがあります

Textタブの位置が変わっています。

f:id:shiraji:20190203135655p:plain
Textタブの位置が左に!!!

デフォルトでは、Designが左で、Textが右。

f:id:shiraji:20190203135757p:plain
デフォルトはこれ

細部までこだわり抜いて作られている感じがします。

Preferenceのパスのコピー方法

これは設定というより機能のお話です。

登壇中もこのブログでも特定の設定画面への遷移を「Preferences | Keymap」のように記述していました。たぶんここを読んでいる方も社内や自分のドキュメントで設定への遷移を書いたことある人いるのではないでしょうか?

これをタイピングするのは、なかなか厳しいです。そこでこの機能を使うと便利です。

f:id:shiraji:20190203165414p:plain
Preferences | Build, Execution, Deployment | Gradle をタイピングするのは大変

左側にあるTree的なメニューにポインターを合わせ、右クリックしてみてください。「Copy Preferences Path」と出てきます。これをクリックすれば、そこまでのパスをコピーすることが出来ます。

f:id:shiraji:20190203165546p:plain
Copyメニューが出てくる

Pluginのインストールを強制する

特定の機能を使っている場合、チームで必須で使うプラグイン揃えたい時があると思います。例えばDatabindingを使っているプロジェクトでDatabinding Support - Plugins | JetBrainsを入れるとか。

登壇で使ったプロジェクトでは、自分がどんなタイピングをしたのか、どんなActionを実行したのかをあとでみやすくなるように、Presentation Assistant - Plugins | JetBrainsを強制していました。

Preferences | Build, Execution, Deployment | Required Plugins

プラグインの強制方法はこの設定画面で、現在使っているプラグインの中から強制するプラグインを選択します。

f:id:shiraji:20190203173216p:plain

これらのプラグインをインストールせずにプロジェクトを開くと、右下のところにエラーが表示されます。

f:id:shiraji:20190203173110p:plain
プラグインがインストールされていない場合、エラーが出る。

このエラーポップアップの「Install required plugin」というリンクをクリックすると、インストール予定のプラグインの詳細が表示されます。OKボタンを押すと、全てのプラグインをインストールしてくれます。

f:id:shiraji:20190203180205p:plain


当日の発表は多分ここまでです。これ以降は時間の都合上、発表することが出来なかったお話です。


設定の共有

ここまで色々設定変更を見てきましたが、これらの設定はチーム内で共有することが可能です。多くの設定はプロジェクトの.idea内に含まれています。

f:id:shiraji:20190203181739p:plain
.idea内に設定ファイルが格納されている

externalDependencies.xmlは必要なプラグインの設定、vcs.xmlはバージョンコントロールの設定だったりします。

ただし、例えば、workspace.xmlのようなその個人の設定ファイルも含まれてしまっていますので、必要に応じて、.gitignoreなどでコミットしないように注意が必要です。

github.com

GitHubのgitignoreにJetBrainsのものが公開されていますので、それを参考にすると良いと思います。

icon.png/icon_dark.pngというファイルがあると思います。これはそのプロジェクトiconとして認識されます。

f:id:shiraji:20190203182650p:plain
プロジェクトのアイコンが表示される

ちなみに、最近Android Studioの対応がされた、Toolboxでもアイコンが表示されます。

f:id:shiraji:20190203182808p:plain
Toolbox便利なのでぜひ使うといいと思います

Android StudioをNotepadにしてみよう!

最後に(最初から?)ちょっとAndroid Studioで遊んでみます。

Android Studioにはいろんなボタンや空白などがあります。これを全て消すとどうなるか!?を試してみます。

f:id:shiraji:20190203183042p:plain
初期表示

「Hide All Windows

f:id:shiraji:20190203183255p:plain
Tool Windowを隠す

「Tabs Placement」を「None」に

f:id:shiraji:20190203183407p:plain
タブが無くなった

「Show line numbers」を「OFF」に

f:id:shiraji:20190203183558p:plain
行番号が消えた

「Status bar」を「OFF」に

f:id:shiraji:20190203183647p:plain
最下部のStatus Barが非表示に

「Navigation Bar」を「OFF」に

f:id:shiraji:20190203183748p:plain
上部のNavigation Barを消した

「Show Gutter icons」を「OFF」に

f:id:shiraji:20190203183900p:plain
行番号の横にあったスペースがなくなった

「Tool Buttons」を「OFF」に

f:id:shiraji:20190203184030p:plain
外枠のボタンが全部なくなった

「Breadcrumbs」を「Don't Show」に

f:id:shiraji:20190203184125p:plain
下部のスペースがなくなった

ここまで来るともうNotepadとほぼ見分けが付きません!画面が有効活用出来そうです!

ちなみに、ここまでやってしまって、最初に戻す方法は用意されていません。Macの場合、~/Library/Preferences/AndroidStudio3.3/optionsフォルダを消せば元に戻せます。実行は自己責任でお願いします!

まとめ

以上、DroidKaigi2019の Android Studio設定見直してみませんか? の詳細でした。

これを聴いてくれた、または読んでくれた方が1人でも設定変えてみたり、他にも面白い設定/機能ないかなー?ってAndroid Studioの探訪をしてくれると嬉しいなーって思います!

宣伝

さて、Ubieでは、こんな感じで、便利なものを積極的に採用して開発を進めています。もし、Ubieに興味出てきたなーって方はぜひ、@shiraj_iにDM下さい!

サーバサイドエンジニア以外にもいろんな職種募集していますので、こちらもぜひ確認してみてください。

speakerdeck.com

GraphQL(Kotlin)とStackdriver Traceの美しさに惚れました。

GraphQL(Kotlin)とStackdriver Traceがすごくいい感じだったから見て欲しい。

実装

ここで公開したアプリに修正を加えてみました。

shiraji.hatenablog.com

github.com

ライブラリの追加

spring-cloud-gcp-starter-traceを使い、Stackdriver Trace*1利用するため、gradleに変更を加えます。

repositories {
    mavenCentral()
    jcenter()
+    maven(url = "http://repo.spring.io/libs-milestone")
}

dependencies {

+    val springCloudGcpVersion = "1.1.0.RC2"
+    compile("org.springframework.cloud:spring-cloud-gcp-starter-logging:$springCloudGcpVersion")
+    compile("org.springframework.cloud:spring-cloud-gcp-starter-trace:$springCloudGcpVersion") {
+        // remove this after 1.1.0.RELEASE
+        exclude(group = "io.grpc")
+    }
+    compile("app.ubie:brave-kt:1.0.0")

https://github.com/ubie-inc/kotlin-graphql-sample/commit/b0aee867adf13e3e2ef41e8c3e8a5979619995f3

exclude(group = "io.grpc")しているのは、1.0.0.RC1よりバージョンが上のspring-cloud-gcp-starter-traceを使うと、io.grpcが複数のバージョンに依存してしまう問題があるためです。以下で問題提起しています。1.1.0.RELEASEで修正が完了する模様です。

github.com

環境変数などを変更

次に、Stackdriver Traceを利用できるように環境変数などを変更しています。 GraphQLのクエリをログ出力するために、graphql.GraphQLのログレベルをDEBUGに変えています。

  cloud:
    gcp:
      trace:
-        enabled: false
+        enabled: true
      logging:
-        enabled: false
+        enabled: true
  sleuth:
    sampler:
      probability: 1.0
@@ -24,3 +24,4 @@ logging:
  level:
    root: INFO
    org.springframework.jdbc.core.JdbcTemplate: DEBUG
+   graphql.GraphQL: DEBUG

https://github.com/ubie-inc/kotlin-graphql-sample/commit/beb23dc3b858c1cd8cbead49d2f7c1a0abd59b21

Scope Spanを使い、さらに見やすく

最後に、brave-ktを利用して、各クエリがどれくらい時間がかかっているのかを確認するTraceを入れます。

-        if (icd.isBlank()) return emptyList()
-        return jdbcTemplate.query(
+        return Tracing.currentTracer().scopedSpan("findKinkiDrugsByIcd") {
+            if (icd.isBlank()) return emptyList()
+            jdbcTemplate.query(
                 //language=SQL
                 """
                 SELECT
                   yj_code,
                   icd
                 FROM
                   disease_kinki_drug
                 WHERE
                   icd = :icd
                 """.trimIndent(), mapOf("icd" to icd), rowMapper
-        )
+            )
+        }

https://github.com/ubie-inc/kotlin-graphql-sample/commit/25e8e477b365f037daa4948dc94b24ff5789709a

brave-ktに関しては以下の記事に書いてあります。

shiraji.hatenablog.com

結果

ライブラリ追加して、ちょこっと見やすい工夫を入れるだけなのですが、以下のような結果が表示されるようになります。

f:id:shiraji:20190116030939p:plain
Scope Spanを使い、各DBアクセスの時間を見えるように

f:id:shiraji:20190116031047p:plain
1クエリ内で発行されたログも表示できる

f:id:shiraji:20190116031125p:plain
リクエストクエリなども見える

特定のクエリに対して、どのSQLがどのタイミングで発行され、どれくらいの時間がかかっているのか?などが一目でわかるようになりました。

感想

めっちゃ便利。この結果が美しくて惚れました 😍

宣伝

さて、Ubieでは、こんな感じで、便利なものを積極的に採用して開発を進めています。もし、Ubieに興味出てきたなーって方はぜひ、@shiraj_iにDM下さい!

サーバサイドエンジニア以外にもいろんな職種募集していますので、こちらもぜひ確認してみてください。

speakerdeck.com

*1:Stackdriver Traceを利用するには https://cloud.google.com/trace/docs/quickstart?hl=ja を参照