heihei blog

Blog icon by Unsplash https://unsplash.com/@virussinside

2018年2月を振り返る

2018年も17%がすでに終わったようです。(恐ろしい)

先月に引き続き、やったことベースで振り返ります。

2月やったこと

DroidKaigiに初めて登壇者として参加した

僭越ながら、DroidKaigiにてFluxについて発表させていただきました。

登壇やDroidKaigi自体の振り返りについては、下記ブログ記事に記載しています。

shoheikawano.com

登壇以外にも、上記記事には書いていませんが、1日目が終了したあとの懇親会にて@hakさんとお話できたのが個人的には良い思い出になりました。いつもhakさんの回をメインに聴いていることや、マッチングアプリ作ってます、お〜どんな感じのなんですか、というような会話をしました。またお話したいです。

他にもKaigiを通して色々な、普段はお話できない方々と新しい交流があったことが何より良かったなと感じています。

改めて、運営の皆様に感謝いたします。m(__)m


DroidKaigiでFluxについて発表したのでここでFluxについて余談ですが、先日、@magiepoohと宅飲みをしているとき(9割は「日村がゆく」を観てゲラゲラ笑っていました)にFluxの話になり、

ぷ「Flux人気になってきたよね」

hei「たしかに」

ぷ「Fluxにはいくつか(δ´ω`)カユイところあるよね」

hei「たしかに」

ぷ「今模索中なんだよね〜」

というような会話をしました。(「たしかに」しか言ってない自分)

(δ´ω`)カユイところの例としては、たとえば

  • 「Viewの状態」を管理したくなった場合にどこで管理するのか(Store?それ以外?)
  • Action/EventをDispatchしないけどActionCreator等に任せたい処理をどこに書くのか

などがあるかも、という話を2人でさらっとですがしました。

今後はそれを解決する形でまた新しい設計が出てくるのかなーと思いました。(「コレで行けるっしょ!」という方はぜひお話したいです〜)

余談以上!次。

DroidKaigi Reject ConferenceにてOkio & OkHttpについて発表した

DroidKaigiから一週間後、DroidKaigi Reject Conferenceがありました。そこで@stsn_jpさんと2人で登壇しました。

こちらについての振り返りブログ記事は下記です。

shoheikawano.com

本記事にも記載していますが、資料準備が間に合わず、会場設営後、最後の最後まで資料作りをおこなっていました。

登壇はノリで決まり、もともと「OkHttpとかOkioとかの有名ライブラリの内部実装しっかり読みたいですよね!?」というところからでしたが、いつの間にか応募して登壇することが決まり、いつのまにかDroidKaigiが終わって「あれ、内部実装まだぜんぜん読めてないぞ!?」となり冷や汗しか出ていませんでした。ですが、登壇後は会場にいらした方々から「面白い」とツイートいただけて、どうにか楽しんで頂けてよかったかなという印象でした。

DroidKaigi Reject Conferenceに関しては最後の懇親会でも多くの方が残ってワイワイお話して楽しかったので来年もぜひ開催したいです。

技術書典のための執筆を始めた

今年の4月に初めて技術書典にて本を出します。職場の同じフロアで働くAndroidエンジニア数名で一冊、有志で出します。

書典では、Okioの内部実装について、15ページ〜20ページほど記載する予定です。 DroidKaigi Reject Conferenceで発表した内容は本当に一部分なので、枚数の許す限りガッツリ書こうと思います。執筆を始めた、といってもはじめたばかりですので、これから頑張ります。

ほかメンバー含めみんな初書典なので、お手柔らかにお願いできればと思います。m(__)m

その他

  • お金2.0を読んだ
  • CloudStudyJam行って初めてGCP, Kubernetesあたりを触った

最後に

今月末、Droidcon BostonにてFluxについて発表してきます。内容の大半はDroidKaigiで発表したものと重なるかもしれませんが、DroiconではDroidKaigiと比べ10分ほど発表時間が長そうなので、資料も更新しDroidKaigiで発表しきれなかった部分についても頑張って発表してこようと思います。リベンジ!

終わったら、経緯や振り返り系のブログを書こうと思います。不安もありますが、初Airbnbも楽しみですのでマイペースにやっていけたらと思います。 今月の振り返りは以上です!

2月もお疲れ様でした〜!

DroidKaigi RejectconでOkio & OkHttpの内部実装について発表した

f:id:shaunkawano:20180217192911j:plain

DroidKaigi RejectconでOkio & OkHttpの内部実装について発表しました

資料はこちらです:

speakerdeck.com

DroidKaigi Rejecton

connpass.com

準備期間としては、DroidKaigiが終わってから本日までの、1週間後と少しでした。

登壇までの背景

前々から有名ライブラリの内部実装読みたいなーと思っていたところ、週1で情報共有会をさせていただいているstsn_jpさんと2人で登壇しましょう!! という流れになり、DroidKaigiのニッチ枠で応募をしました。

ですがこちらのCFP通らなかったため、今回、DroidKaigi Rejectconで枠がまだあるという話をきいて応募させていただきました。

想像してたけど、想像以上だった

OkioやOkHttpといったライブラリは、最近のAndroidエンジニアであればきっと多くの方がお世話になっているであろうものです。 ただ、ここまで有名でありあがら、内部コードについての説明等はそこまでインターネット上を探しても見つからず、さらにJake WhartonさんやJesse WilsonさんのGithub Activityを見るに、日々活発に開発されているライブラリなだけに、詳細を知っておくことは大事そうだな、と感じていました。

DroidKaigi終わってから本当に少しずつ読み始め、前日、前々日から本格的にコールドリーディングと資料作りを始め、大きな題材のわりに準備期間が短かった、と反省せざるを得ません。コールドリーディングによって得た知見や今回発表できなかった内容などはまた別記事でまとめるとして、SocketやBuffer周りの処理だったり、ThreadなどJava始めた頃に勉強はちょっとしたけど最近ぜんぜん触っていない、意識できていなかったようなものに対する理解だったり、本当に基礎的なところで勉強しないといけない、と感じることが多々ありとても刺激的な準備期間だったと思います。

DroidKaigiの後だったこともあり、今回の機会がなければきっとここまでインプットできなかったであろうと感じています。

改めて、お誘い、一緒に応募していただいた@stsn_jpさん、運営等で大変お世話になりました@heki1124さん、@shihochanさん、改めてありがとうございました。

最後に

面白い!といってもらえて嬉しかったです!

STEP By STEPやっていきたい!(๑•̀ㅂ•́)و✧

以上です!

DroidKaigi 2018にて、Flux for Androidについて発表した

はじめに

DroidKaigi運営の方へ、本当にお疲れ様でした!!

たくさんの知見を共有する・してもらうだけではなく、初めて出会う方はもちろん、GitHubTwitterでは知っていたけどリアルで話したことはなかった他のエンジニアの方々や海外出身の方々とも交流することができて、本当に楽しかったです。

f:id:shaunkawano:20180210115329j:plain
こちらは@pside氏作の周辺の音を聞き取り画面に表示するビジュアライザ

発表に向けて

DroidKaigiでは、Fluxについての発表をしました。

もともとは、Fluxの概要+実務で感じているFluxのいいところやイケてないところをざっくり言語化して発表しようと考えていました。

しかし、たとえこちらが言語化できたとしても、ある程度の知識や共感してもらえる「前提」がなければ、メリットをよりうまく説明したりスッと実感してもらうことはできないのではないか、と準備期間後半あたりに気が付きました。さらに、下記は自分がプロポーザルに記載した内容なのですが、

In this talk, I'll talk about flux architecture as one of the solid solutions for managing states within Android application; by achieving unidirectional data flow, we aim to think less, focus more on feature development, and scale faster.

(Androidアプリ開発における状態管理問題を解決する設計の1つとしてFluxを紹介します。データの流れを単一方向にすることで、状態管理であったりロジック管理について無駄に考える・悩むことを減らし、代わりに素晴らしい機能について考えたり実装したりする時間をもっと作り、アプリを大きく(スケール)させましょう!)

このようなプロポーザルの内容を準備の途中からあまり意識できていませんでした。(事業部内の共有会にて途中までの資料を共有させていただいた際に気づかされました。。)

改めてどういう内容を発表しようか、作り初めていた資料を修正し、最後まで悩み、社内の後輩・同期・先輩エンジニアの方々にご相談させていただいたりしました。皆様改めてありがとうございました。特に@kaelaela氏については、発表練習を一緒に何度か行ってくれました。ありがとう!

最終的な発表内容

最終的には、プロポーザルの内容に沿った上で、自分が現時点で一番感じているAndroidアプリ開発にFluxのメリットや悩ましいところをそのまま発表したいと思いました。

ということで、アプリの中でのデータの流れを単一方向にすることと、Storeを唯一のデータを管理するコンポーネントと位置づけることが重要であるということを前提に、FluxをAndroidアプリ開発に採用することのメリット、悩ましいところは以下であると個人的に結論付け、共有したいと考えました:

メリット

  • Fluxの単一方向性という考え方やアーキテクチャの図式自体がシンプルであること
  • Fluxの各パーツの責務がはっきりと分かれているため、実装コードがある程度統一されること
  • 機能ベースでFluxのデータの流れを実装することで、一度実装したFluxのパーツや内部ロジックを、新しい機能や画面を追加する際に再利用できること
  • Kotlinのsealedクラスを用いたり、Actionのクラス名を分かりやすいものにすることで、Storeの内部ロジックを読むことでアプリの仕様が理解できること

これらのメリットを享受することで、Androidの開発におけるデータの管理方法や機能追加の際に考えたり悩んだりする時間を減らすことができます。さらに、コードを書く以外の部分において、たとえば新しいメンバーがチームにジョインした際にも、新しいメンバーが早い段階で実力を発揮でき、最終的にはスケールしやすいアプリになる、という発表をしようと思いました。

もちろんいいところばかりではなく、悩ましいところも紹介したいと考えました。

悩ましいところ

  • 本来のDispatcherの役割が、いわゆるEvent Busである(アプリ全体に対してデータを伝達する)
  • ActionCreatorStoreどちらに処理を記載したほうがいいのか、たまに悩む

これらを踏まえ、最終的にできたスライドは下記です

speakerdeck.com

登壇が決まってから登壇するまでざっくり

登壇が決まった:

2017年の末からすでに緊張しているのを感じる:

そして登壇直前の最後のツイートで緊張しすぎて誤字のfoe:

英語での発表だったため、海外出身の方がたくさんいるのでは、と予想していたのですが実際は5人程度とかで残りは日本人の方でした。笑

反省

1日目終了後の懇親会にて、@wasabeef氏に「日本を楽しんでもらいたいなら何か紹介しなよ、ラーメンとか」、と勧められたため、ラーメンのお店はどこが良いのか自分の中でも一番が決まっていなかったため、海外出身の方にとって珍しい日本のコンビニエンスストアの便利さと、数あるコンビニエンスストアの中で僕が一番大好きなセブンイレブンの「ななチキ」について、登壇前に紹介をしました。これができたのは大きな自信になりました。 ただ、@wasabeef氏にはラーメンのほうがよかったな〜と言われたので、そこは反省です。

発表は、案の定練習の時のようにうまくはいかず、カミカミだったり、最後、時間的にはほぼぴったりだったのですが、タイマーの音に驚いて「Enjoy Japan!」と叫んで終了しました( ゚∀゚)・∵. グハッ!! 恐怖でYoutube動画がUPされても自分のだけは絶対に見れない形になりました。ですが、お褒めのツイートを頂けたり、オフィスアワーで初めて声をかけてくださった方がいたり、会社の後輩氏のツイートからスライドの改善すべき点が見えたり、良かったことも失敗したことも含め、発表できてよかったと改めて痛感しました。

反省としては、設計周りの発表をする際には前提がないと、ただただ簡単なサンプルの一例を紹介するだけでは旨味が伝わらない、ということに最初の方で気づけなかったことです。50分枠のほうが適切だったかも、と感じました。

時間配分に関しては、早めに終わる分には問題ないので早めに終わるように時間配分するくらいが良いのかもと思いました。自分の場合は本番中、まだ時間あると思って詳細を話していたらすぎてしまったので、「時間ある」と思わずさらっと終わればよかったな、と反省しました。

ぜひまた発表したいです。

あとは、これはイベント全体を通してですが、他登壇者の方々ともっとお話できればよかったな、と思いました。ここが一番反省。来年はもっとたくさんの方と仲良くなるぞー!!!

ツイート

終わってからfoeに気付いた自分と、それにいいねをくださるDroidKaigi公式の優しさ:

皆様ありがとうございます!!

最後に、いくつか撮った写真を共有します。

f:id:shaunkawano:20180210122218j:plain:w360
DroidKaigi208いよいよ感

f:id:shaunkawano:20180210124218j:plain:w480
ウェルカムトーク会場

f:id:shaunkawano:20180210121001j:plain:w480
Androidで動画コンテンツを扱うTipsについて発表している@takusemba氏(ブレてる...)

f:id:shaunkawano:20180210121116j:plain:w360
登壇前、緊張がピークに達している@kaelaela氏

f:id:shaunkawano:20180210121714j:plain:w360
ProGuardについて発表している@stsn_jp氏

f:id:shaunkawano:20180210122255j:plain:w360
PrePartyにて出てきたDroidくん🍻

f:id:shaunkawano:20180210122248j:plain:w360
2日目同じ時間帯にInstant Appsについて発表した@_a_akira

f:id:shaunkawano:20180210122250j:plain:w360
会社同じだけど初めて喋って仲良くなったEoinさんと@takusemba

f:id:shaunkawano:20180210122223j:plainf:id:shaunkawano:20180210122227j:plain
懇親会会場はキラキラしてた


f:id:shaunkawano:20180210124521j:plain:w480
2日目終了後、@stsn_jp氏と2人でやよい軒で打ち上げ〜(DroidKaigi Rejectonも頑張るぞ!)

改めて、運営の皆様、本当にありがとうございました!!

以上です!

Presentation(β version) for DroidKaigi "Flux: Utilize unidirectional data flow to think less and scale faster"

This is the β version of DroidKaigi session "Flux: Utilize unidirectional data flow to think less and scale faster".

If you have anything specific you would like to know about Flux or if you find something irrelevant/typo in this presentation feel free to let me know! (@shaunkawano on Twitter).


先日の記事にて、「ある程度できた段階で資料を公開します」いうことを書いていました。

本日、ある程度のところまで資料ができたと思うので公開します。

先日の記事の中で、

なるべく早く公開予定(多分本日中…)

と書いていたにもかかわらず今日になってしまいました。(汗)

資料は、引き続きこの資料に修正を加えていく予定のため、β版です。

本セッションは中級者・上級者向けのセッションなので、Fluxの入門やチュートリアル的なものではなく、ある程度実際の業務の中での気づき・躓くところだったり「ここが良い!」というところを共有できればと考えてはいるのですが、このままだとほとんどその部分が口頭ベースになってしまいそうなため、ううーと思っています。こういう内容が聞きたい!だったりご指摘等ありましたらTwitterのメンションやDMでご連絡いただけると嬉しいです。

引き続き精進します〜〜

2018年1月を振り返る

2018年も10%ほどがすでに終わったようです。(恐ろしい)

前置き

個人的に、技術のインプット、アウトプットをどんどんしていくためのツールとしてブログ使っていたのですが(そんなにたくさん書けていないのですが、、)今年は、個人の振り返りなど自分事の内容も書いていきたいという思いがあります。ブログは書き続けていきたいと思う一方、技術のことだけ書いていてはいつか書かなくなりそうだな、であれば色々なことを書いたほうが個人的にはなんとなく続きそうだな、と感じたことが大体の理由です。また、通常の日記などもそうですが、あとあと読み返したときのちょっとした発見や振り返ったときの楽しみのために書く、というのもモチベーションになっているのかもしれません。(とはいえ、いつまで続か分かりませんが。)

ということで、雑に1ヶ月の振り返りブログをちょこちょこ書いていければいいかなと思っています。

1月やったこと

1月大まかにやったことを時系列に書きまとめます。

Git Push Hackathonをリリースした

ネイティブエンジニア志望の学生限定のハッカソンイベントを年末から社内のネイティブエンジニア数名で企画していたものを出しました。

github.com

株式会社サイバーエージェントの採用イベントページにも掲載されました。

Git Push Hackathon | 株式会社サイバーエージェント

(ここから少しだけ宣伝)

締め切りは2月末までなのでまだまだ時間あります。完全リモートなハッカソンで、エントリーしたらコードを書いてプッシュするだけ!賞品もあります!ネイティブエンジニア志望の学生さんご興味あればぜひ!

宣伝以上!

Shibuya.apkにて初めて発表した

Android SDKのソースコードを読む際に便利なツール群について発表をしました。2018年初めての発表だったことと、Shibuya.apkでの発表は初めてだったこともあり(?)、Romain GuyさんとRoman Nurikさんを呼び間違えてしまうくらい緊張しました。内容は下記記事にまとめています。

shoheikawano.com

Potatotipsに参加した

potatotips.connpass.com

オイシックスドット大地株式会社のオフィスに初めて行きました。

AutoDisposeというライブラリについて、知らない方向けに入門的なLTを行いました。 

その他

その他は1月は

  • ゲームは、Shadowverse
  • アニメは、ゆるキャン△ \コンニチハ/

にハマっています。

最後に

現在、DroidKaigiの資料作りを行っています。 本当はもっと早くに完成してリハーサルをひたすらこなしている状態を想定していたのに…

英語での発表となりますが、2日目の11:20-11:50にて、Fluxについて発表予定です。

発表予定の内容や資料は、資料がほぼ完成した段階で、なるべく早く公開予定(多分本日中…)ですので、もし資料や発表予定の内容に興味がある方がいましたら当日少しでも構いませんので聞きに来ていただけるとうれしいです!

droidkaigi.jp

以上です!

1月もお疲れ様でした〜

【保存版】Android SDK内部のソースコードを読む際に役立つ(かもしれない)ツールやウェブサイト6選

f:id:shaunkawano:20180113171624p:plain

Android SDKのソースコードを読みたい

Androidアプリ開発をしていると、「Android SDKのソースコードを読みたい」、と思うことがしばしばあります。

  • 思わぬバグに出くわしてしまったが調べても調べても原因がつかめない
  • (例えば)ViewPagerなどのAndroidが提供しているViewコンポーネントの動きを独自に変えたい(スクロールの際のアニメーションスピードを変更したい)

といった場合などです。(もちろん上記以外にもあるかと思います。)

本記事では、Android SDK内部のソースコードを読む際に役立つ(かもしれない)ツール群について、shibuya.apk#21にて5分LT枠で発表した内容を元に紹介しています。

shibuya.apkでのスライドは本記事下部に埋め込み追加しております。尚、本記事で紹介するツールやウェブサイトは下記です:

  • SDK Manager(Android Studio)
  • Git at Google - android Git repositories
  • GitHub - ASOP Mirror repositories
  • OpenGrok(Developer Collaboration Project)
  • AndroidSDKSearchExtension
  • SdkSearch

ここから、1つずつ雑に紹介していきます。

Android Code Search

f:id:shoheikawano:20210123094211p:plain※2020/06/16更新 もはやこれ一つが全て感があります。

https://cs.android.com/

  • Android
  • Androidx
  • Android Studio

それぞれのソースコードを、ファイル名やクラス名等軸で検索できます。 リリース前の最新のソースコードもこちらに反映されているので、こちらを使えば大半の最新コードは確認できるかと思われます。

SDK Manager(Android Studio)

SDK Managerとは、Android開発において重要なSDK関連のツールやコンポーネントなどをインストールしたりアップデートするためのものです。Android Studioでは、下記画像のボタンを押下することで起動できます。

f:id:shaunkawano:20180113171555p:plain

SDK Managerを利用することで、SDK Platformのパッケージをインストールすることができます。パッケージインストール後は、Android Studio上でAndroid Platformのクラス名やメソッド名からコードジャンプすることができるようになります。コードジャンプすることで、内部実装はもちろん、各クラスやメソッドの詳細についてのドキュメントレベルのコメントなどをAndroid Studio上で確認できるようになります。Androidアプリ開発を仕事にしているエンジニアは、日々このツールを活用しているのではないでしょうか。

SDK Managerについての公式ドキュメントはこちらのようです: IDE および SDK Tools の更新  |  Android デベロッパー  |  Android Developers

Git at Google - android Git repositories

android Git repositories - Git at Google

Googleが管理している、androidソースコードのgitレポジトリ一覧です。Google Gitと記されているとおり、GoogleがGitを用いて独自管理しています。(GitHub上で管理されているAndroidのソースコードについては次に紹介しています。)

たとえばplatform/frameworks/base - Git at GoogleではAndroidフレームワークのクラス群などのソースコードを閲覧できます。

GitHub - ASOP Mirror repositories

github.com

Git at Google - android Git repositoriesのGitHub上のミラープロジェクトです。

使い慣れているGitHub上でソースコードを読みたい!という方はこちらを利用すると良いかもしれません。先程のplatform/frameworks/baseのレポジトリはこちらです:

github.com

また、下記のような活用方法も便利そうですね!

OpenGrok(Developer Collaboration Project)

github.com

Oracle社が提供しているソースコード検索、クロスリファレンスをするためのツールです。一般的な使い方としては、Tomcatのようなサーブレットコンテナを用いてローカル上で動かすようです。しかし、Developer Collaboration Projectとよばれる有志のプロジェクトによって、このOpenGrokを使ったソースコード検索サービスがインターネット上に公開されて、そちらを利用することもできます。Oreoのソースコードも検索可能になっています。

sites.google.com

 

AndroidSDKSearchExtension

github.com

Androidのソースコード検索や閲覧を容易にするためのChromeの拡張機能です。

インストール後、Chromeのアドレスバーに ad と打ち込み tab を押下すると、アドレスバーの左にAndroid SDK Searchという文字が表示されます。そこから、たとえばVeiwPagerと打ち込みEnterを押下することで、developer.android.com上のViewPagerのドキュメントページに遷移することができます。

さらに、拡張機能によってdeveloper.android.comのタイトル下部にview sourceというボタンが設置されます。このボタンを押下することで、対象クラスのソースコードのページに遷移することができます。

f:id:shaunkawano:20180113180021p:plain

遷移先ソースコードのページは標準で二種類用意されていて(android.googlesource.com / github.com)、拡張機能の「オプション」画面にて変更することができます。

f:id:shaunkawano:20180113180259p:plain

SdkSearch

github.com

最後は、Jake氏によるSdkSearchというAndroidアプリです。プロジェクトをcloneしDebugビルドをすることで通常のアプリとして利用することができます。 アプリは、検索バーと結果を一覧表示するのみのシンプルなもので、検索結果に引っかかるAndroid SDKの内容をタイル形式で一覧表示してくれます。 検索結果の要素をタップすることでdeveloper.android.comのドキュメントページに遷移し、「More Options」アイコンを押下することで、シェアやソースコードのページに遷移することができます。このアプリを利用することで、たとえば電車の中で「( ゚д゚)ハッ!今すぐViewPagerのソースコードが読みたい!」と思ったとしても、文字通りすぐにソースコードを読むことができるでしょう..!

また、このアプリはkotlin-coroutineやkotshi, room, sqlbright, sqldelightなどモダンなライブラリを活用して作られていて、実装コード自体をしっかり読むことで勉強になることもありそうだと感じています。Jake氏さすが〜。

最後に

shibuya.apkでの発表資料は下記です。

今回紹介したツールやウェブサイト以外にもAndroid SDKのソースコードを読む上で便利なもの、よくやることなどありましたらご連絡いただけると幸いです!

以上です!

 

Notes - droidcon NYC 2017: Upgrading to Moshi

※Notes記事では、英語のセッション動画やポッドキャストの内容を(雑に)英語でメモに書き残すことを行っています。本記事は、あくまで動画を見ながら、参考程度に読んでいただくことを想定しています。Notes記事には雑メモ程度のものだったり、書き起こしのようなものもあります。これから実際の動画を見る際には、本記事の内容が少しでもお役に立てば幸いです。(内容において不備、誤字脱字等ありましたら気軽にご連絡いただけると嬉しいです。)

本記事は、droidcon NYC 2017 - Upgrading to Moshi - YouTubeの記事です。

今現在、AndroidにおけるJsonシリアライズ・デシリアライズを行なうライブラリの中では、Gsonが一番人気であると個人的には感じているのですが、 本セッション動画では、Moshiとは何なのか、MoshiがGsonよりも優れている点(またはGsonが提供していてMoshiが現状提供していないAPIについて)、そしてGson→Moshiへの置き換えのメリットや方法などについて紹介されています。(※本セッション動画にはmoshi-kotlinについての説明はほとんどありません。Kotlinに関する話というよりは、MoshiというJsonパーサーライブラリについての説明に重きをおいた発表となっているようです。)

f:id:shaunkawano:20180109131119p:plain

Upgrading to Moshi

What is Moshi?

JSON serialization library for Java with a streaming and object-mapping API.

  • Moshi is kind of "Gson 3"; it is kind of Gson 2 but kind of like "Gson Lite"
  • It takes great things from Gson API and removes extra part of Gson API that not many people are using

Why update from Gson?

  • Gson often contains breaking API changes
  • Application using Gson does not often update Gson dependnecy
  • If the code already works with Gson then not necessarily need to upgrade; you are not going to obtain amazing performance optimization by switching from Gson to Moshi

Why update from Gson: Gson

  • In Inactive development
    • Breaking changes
    • Not many people update to use the latest version
  • Too lenient
    • "Platform type issue"
      • "Date" type adapter
      • Implementation change in the platform affects your adapter that has relied upon the previous version of the platform implementation
  • Large API
  • Inconsistent exceptions(e.g. IOException may occur when it actually should be data exception).
  • ~188KB, 1345 methods (Moshi: 112KB, 759 methods)

Why update from Gson: Moshi optimizations

  • Share buffer segments with other Okio users.
    • If you use OkHttp or Retrofit or any other libraries that rely on Okio
  • Avoid allocating strings while deserializing.
    • JsonReader.selectName(Options) allows you to pre-allocate memories.

How to upgrade?

FieldNamingPolicy

=> Defining model classes as actual JSON response may be clearer. (Even using sneak_cases as wrigin sneak_cases for layout_ids in Android)

Reflective field naming policy

  • @SerializedName("the_name") => @Json(name="the_name")

Streaming API

  • It's the same!
  • com.google.gson.stream.JsonReader => com.squareup.moshi.JsonReader
  • com.google.gson.stream.JsonWriter => com.squareup.moshi.JsonWriter
  • Moshi bonus
    • JsonReader.Options
    • JsonReader.setFailOnUnknown

JsonReader.Options

Prepare strings ahead of time:

Options.of("key1", "key2")

Read out directly from the input source:

JsonReader.selectName(options), JsonReader.selectString(options)

returns index of string in Options.

setFailOnUnknown

  • JsonReader.setFailOnUnknown(true)
  • Useful for debugging, not for production app
  • Fail when JsonReader.skipValue() is called to ensure you are not missing any JSON data while debugging

Object Mapping

  • TypeAdapter => JsonAdapter
  • No document-level API like Gson.fromJson()
  • Gson.getAdapter(Type) => Moshi.adapter(Type)
  • Cache your adapters!
    • Object Mapping without bad leniency
      • Platform types require explicitly registered JsonAdapters.
      • moshi.adapter(java.util.Date.class)
      • moshi.adapter(java.util.ArrayList.class)
      • moshi.adapter(android.graphics.Point.class)
    • JsonAdapter wrappers:
      • serializeNulls(), nullSafe(), lenient(), indent(String), failOnUnknown()
    • TypeToken => com.squareup.moshi.Types factory methods

Moshi preferes plain Java's java.lang.reflect.Type. => TypeToken.getParameterized(List.class, String.class) => Types.newParameterizedType(List.class, String.class)

Unknown Enums

enum Exercise { RUN, JUMP, WALK }

Gson: exerciseTypeAdapter.fromJson("jog") => returns null Moshi: exerciseJsonAdapter.fromJson("jog") => throws JsonDataException

EnumWithDefaultValueJsonAdapter => API in Moshi to have fallback enums?

JsonQualifier

Special-case type qualifiers:

class Data { @JsonAdapter(WrappedStringTypeAdapter.class) String string; }

=>

@Retention(RUNTIME) @JsonQualifier @interface WrappedString {}
class Data { @WrappedString String string }

WrappedStringTypeAdapter.java

class WrappedStringTypeAdapter extends TypeAdapter<String> {
  String read(JsonReader reader) throws IOException {
    reader.beginObject();
    String string = reader.nextString();
    reader.endObject();
    return string;
  }
}

Easier JsonAdapters

Traditional JsonAdapter.Factory code implementation looks like this:

class PointJsonAdapterFactory implements JsonAdapter.Factory {
  JsonAdapter<?> create(Type typem Set<? extends Annotation> annotations, Moshi moshi) {
    if (Types.getRawType(types) != Point.class) return null;
    return new JsonAdapter<Point> {
      Point fromJson(JsonReader reader) { ... }
      void toJson(JsonWriter writer) { ... }
    }
  }
}
  • A lot of boilerplates
  • The code tends to be error-prone codes
    • Often the code is not tested

Blow is the easier version:

class PointJsonAdapter {
  @FromJson Point fromJson(JsonReader reader) { ... } 
  @ToJson void toJson(JsonWriter writer, Point value) { ... }
}

It uses reflection API; when you add this object to Moshi.Builder then Moshi will create the factory for you

Here is the even easier ones:

@FromJson Foo fromJson(JsonReader reader)
@FromJson Foo fromJson(JsonReader reader, JsonAdapter<any> delegate, <any more delegates>)
@FromJson Foo fromJson(Bar value) // Bar is already a type that can be deserialized

@ToJson void toJson(JsonWriter writer, Foo value)
@ToJson void toJson(JsonWriter writer, JsonAdapter<any> delegate, <any more delegates>)
@ToJson Bar toJson(Foo value) // Foo is already a type that can be serialized

Advanced: Polymorphic types

class Animal { String type; }
List<Animal> animals = animalAdapter.fromJson(source)

Gson: JsonElement(JsonObject, JsonArray,

Gson: RuntimeTypeAdapterFactory Moshi: ???

Updating piecemeal

Retrofit

retrofit/AnnotatedConverters.java at e6a7cd01657670807bed24f6f4ed56eb59c9c9ab · square/retrofit · GitHub

@Moshi for new code

Retrofit retrofit = new Retrofit.Builder().baseUrl(server.url("/"))
  .addConverterFactory(new AnnotatedConverterFactory.Builder()
    .add(com.example.Moshi.class, moshiConverterFactory)
    .add(com.example.Gson.class, gsonConverterFactory)
    .build())
  .addConverterFactory(gsonConverterFactory) // Fallback
  .build();

interface Service {
  @GET("/new_endpoint") @com.example.Moshi Call<Foo> newEndpoint();
  @GET("/old_endpoint") @Gson Call<Foo> oldEndpoint();
  @GET("/old_endpoint") Call<Foo> oldEndpointDefault(); // Will use Fallback converter
}

AutoValue with Moshi

github.com