なるべくコードを書かないandroid開発
TRANSCRIPT
![Page 1: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/1.jpg)
なるべくコードを書かないAndroid開発
株式会社ミクシィ・株式会社Diverse
@kikuchy
![Page 2: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/2.jpg)
Who?
@kikuchy菊池 紘株式会社ミクシィ ‑‑(出向)‑‑> 株式会社DiverseAndroidの前はWebのフロントでJavaScriptとか書いてましたShibuya.apk, Roppongi.aar, Kotlin勉強会など
![Page 3: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/3.jpg)
おわび
Kotlinの話が20分枠に収まりきりませんでした
許可いただければお話しします
資料を後ほど公開します & 懇親会でお声掛けください
![Page 4: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/4.jpg)
想定リスナー
二人以上で開発していて
製品のコードの保守が大変だと感じている人
![Page 5: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/5.jpg)
「私のことかも!?」
と思った方は挙手
![Page 6: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/6.jpg)
( ´ ▽ )ノ
![Page 7: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/7.jpg)
コードの保守は大変!!
![Page 8: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/8.jpg)
保守のコスト
と聞いてどんなコストを想像しますか?
![Page 9: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/9.jpg)
人件費
保守にかける時間
気持ち的な問題
![Page 10: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/10.jpg)
たくさん書くとそれだけ負債が増える(›´ω‹ )
![Page 11: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/11.jpg)
書かなければ良い!!!!!
![Page 12: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/12.jpg)
人間が保守するコードを減らせば管理コストは減らせる
![Page 13: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/13.jpg)
どうするか
コンパイル時にコードを自動生成すれば、生成したコードは管理の必要がない
ジェネレーターだけ管理していれば良い
![Page 14: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/14.jpg)
( ´・ω・ )「でも新規開発じゃないと、フレームワーク変えるとか言語変えるとか無理じゃね」
![Page 15: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/15.jpg)
大丈夫!\\ ٩( 'ω' )و //
![Page 16: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/16.jpg)
aptだったら一部分から使い始められる!
チームに「コードを少なくする」ことに対して前向きになってもらおう!
![Page 17: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/17.jpg)
apt1. aptとは2. 使い所3. できること4. 作ろう!
![Page 18: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/18.jpg)
apt1. aptとは2. 使い所3. できること4. 作ろう!
![Page 19: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/19.jpg)
1. aptとは
![Page 20: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/20.jpg)
JSR269 =
Pluggable Annotation Processing API
![Page 21: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/21.jpg)
Android界隈ではaptと呼ばれることが多いようなので 今スライドではaptと呼びます。
![Page 22: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/22.jpg)
コンパイル時にアノテーションを見て何かしらの処理をする仕組
み。 ソースコードを生成することもできる。
![Page 23: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/23.jpg)
apt1. aptとは2. 使い所3. できること4. 作ろう!
![Page 24: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/24.jpg)
2. 使い所マッピングの手間を減らす
何かしらの変換・対応作業
例) ButterKnife R.id.* のViewをクラスのフィールドに対応させ
る
例) ormaDBの行をPOJOに、カラムをフィールドに対応さ
せる
「ライブラリにとって未知のフィールドやメソッド」へ
アクセスできる
![Page 25: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/25.jpg)
2. 使い所クラッシュ(ランタイムエラー)の発生をコンパイル時に前
倒しする
例) R.java 文字列でlayoutファイル名やIDを指定しているとtypoの危険性が
クラッシュはユーザー体験にとって大きなマイナス
コンパイルエラーとして前倒しできればすぐミスに
気付ける
![Page 26: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/26.jpg)
apt1. aptとは2. 使い所3. できること4. 作ろう!
![Page 27: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/27.jpg)
3. できること作例
POJOを HashMap<String, String> に移し替えるPOJOにアノテーションをつけるだけでOKコンパイル時に生成されるコード
POJOの各フィールドを
指定のコンバーターでStringにコンバートし
指定のkey名でHashMapにputする
![Page 28: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/28.jpg)
@ToQueryMap public class BbsCreateRequestBody { @QueryParam(name = "message", adapter = StringTypeAdapter.class) public String message;
@QueryParam(name = "category_code", adapter = EnumToStringTypeAdapter.class) public BbsCategory categoryCode;
@QueryParam(name = "title", adapter = StringTypeAdapter.class) public String title; }
Serializer<BbsCreateRequestBody> serialzer = new BbsCreateRequestBodySerializer() Map<String, String> serialized = serialzer.serialize(request);
![Page 29: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/29.jpg)
あなたのコーディングにどう応用できそうでしょうか?
![Page 30: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/30.jpg)
apt1. aptとは2. 使い所3. できること4. 作ろう!
![Page 31: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/31.jpg)
4. 作ろう!
rejasupotaroさんの『Androidでaptのライブラリを作る時の高速道路』が詳しい
http://qiita.com/rejasupotaro/items/b9b89f88348222b46708
ここに書かれていない、覚えておくと便利なTipsをご紹介
![Page 32: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/32.jpg)
(以降の話の前提)
Java Libraryの module を2つ追加
![Page 33: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/33.jpg)
アプリから使うモジュールに、使いたいアノテーションを定義し
ておく
// RetentionをSOURCEにすると // コンパイル後はこのアノテーションが消えてくれる @Retention(RetentionPolicy.SOURCE)
// Targetを指定するとアノテーションできる場所を限定できる @Target(ElementType.TYPE) public @interface ExampleAnnotation {
// 値を持たせたかったらvalueなどを宣言する public int value(); }
![Page 34: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/34.jpg)
コンパイル時に走るプロセッサを定義する
ソースコード以外も生成できますが、今回はソースコードを生成
// Google の AutoService を使うとメタデータの生成が楽 @AutoService(Processor.class) public class ExampleProcessor extends AbstractProcessor { Filer filer; Types typeUtils; Elements elementUtils; Messager messager;
![Page 35: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/35.jpg)
// プロセッサ初期化時に呼ばれる // 便利なインスタンスが渡されるので取得しておく @Override public synchronized void init( ProcessingEnvironment processingEnv) { super.init(processingEnv); // Filer#createSourceFile にJavaソースコードをStringで渡すと // javaファイルを作ってくれる filer = processingEnv.getFiler(); // TypeMirror を取得したり 具体的なTypeを取得したりできる typeUtils = processingEnv.getTypeUtils(); // Java 構文の要素から子要素を取得したりできる elementUtils = processingEnv.getElementUtils(); // 警告やエラーメッセージの出力に便利 messager = processingEnv.getMessager(); }
![Page 36: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/36.jpg)
// このプロセッサでサポートするアノテーションを決める @Override public Set<String> getSupportedAnnotationTypes() { Set<String> types = new HashSet<>(); // アノテーションの名前はFQCNでないといけない types.add(ExampleAnnotation.class.getCanonicalName()); return types; }
Overriveしない場合、このプロセッサにつけた
SupportedAnnotationTypes アノテーションに書かれた型がサポート
される
@SupportedAnnotationTypes("net.kikuchy.aptsample.ExampleAnnotation") @AutoService(Processor.class) public class ExampleProcessor extends AbstractProcessor {
![Page 37: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/37.jpg)
ソースコードの生成と書き出しには square/javapoet を使うと楽 https://github.com/square/javapoet
// ソースコードを生成して Filter で書き出す処理を書く @Override public boolean process( // 今処理を要求されているアノテーション Set<? extends TypeElement> annotations, // ラウンドの情報 RoundEnvironment roundEnv) { // RoundEnvironment#getElementsAnnotatedWith を使うと // アノテーションがついた構文要素を取得できる for(Element elem : roundEnv. getElementsAnnotatedWith(ExampleAnnotation.class)) { // ソースコードの生成と書き出し ... } // 後続のプロセッサにアノテーションの処理を渡すか否か return false; }
![Page 38: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/38.jpg)
注釈処理のラウンド
process が何度も呼ばれる(ラウンド)
生成したソースコードに対しても注釈処理が必要なため、何
度も呼ばれる
通常は2回 JavaFileObject#openWriter に2回書き込もうとすると2回目は例外が出る
Pluggable Annotation Processing API 使い方メモ http://qiita.com/opengl‑8080/items/beda51fe4f23750c33e9
![Page 39: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/39.jpg)
ラウンド対策
try‑catch2回目に出る例外を握りつぶす
プロセッサのメンバに処理済みかどうか記録しておく
ButterKnifeなどがこれ
![Page 40: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/40.jpg)
生成したコードを使う
一度コンパイルをかければ生成される
aptプラグインを使っていれば、生成後はAndroidStudioの補完機能でも呼び出せる
ButterKnifeのように生成コードを隠蔽する方法もある
クラスの動的ロードが必要なのでProguard設定が必要
// 生成されたViewBinderクラス類は動的ロードされている ButterKnife.bind(this);
![Page 41: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/41.jpg)
aptの補足
![Page 42: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/42.jpg)
aptを使ったAndroid向けライブラリButter KnifeDagger2DeepLink DispatcherPermissionsDispatcherOrmaIntentBuilderFragmentArgsAndroidAnnotationskvs‑schemeFlender
etc
![Page 43: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/43.jpg)
Kotlin
![Page 44: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/44.jpg)
保守コードの減量とKotlinの関係
そもそものコード行数が少なければ、保守コストも少なくて済む
Javaは冗長になりがち、短く書ける言語を使おう
Kotlinもプロダクトの一部分から使い始められる
Java Compatible!!
![Page 45: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/45.jpg)
もうみなさんKotlinはご存知だと思いますので 少しだけマイナー気味で、コード短縮に効果のあることだけ紹介
します。
![Page 46: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/46.jpg)
スコープ関数
apply と let を使うと便利なことが多いです
val intent = Intent(context, NextActivity::class.java).apply { // このスコープのthisは☝のIntent putExtra("hoge", "hogehoge") putExtra("fuga", "fugafuga") }
nullableVal?.let { // nullableValがnullだとこのスコープは実行されない // it (= nallableVal)がnonnullであることが保証される it.doSomething() }
業務でKotlinを書いている僕がKotlinを書く際に個人的に注意していること
http://qiita.com/magie‑pooh/items/b1179af28f5e0d50b62a
![Page 47: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/47.jpg)
Class DelegationEffective Javaなどで言われている「継承より合成」を圧倒的簡単
さで実現
class CustomList<E>(private val base: ArrayList): List<E> by base { override fun add(elem: E) { print("${elem} is added!") base.add(elem) } }
KotlinのClass Delegationおさらい http://sssslide.com/speakerdeck.com/ntaro/kotlinfalseclass‑delegationosarai‑number‑kotlin‑sansan
![Page 48: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/48.jpg)
Property DelegationAndroidでは頻発する遅延評価が簡単に
// in Activity private val hoge by lazy { intent.getStringExtra("hoge") }
// KotterKnife 使用 private val userName: EditText by bindView(R.id.user_name)
Delegated Properties で遊ぼう(スライド版) http://qiita.com/kikuchy/items/55ea0748a5850925349a
![Page 49: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/49.jpg)
こういう話をした理由
![Page 50: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/50.jpg)
むかーしむかし、あるところに、Activity1ファイルで4000行を超えるソースコードがありました。
![Page 51: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/51.jpg)
4000行超え
![Page 52: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/52.jpg)
つらい。
![Page 53: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/53.jpg)
その他のActivityも2000行クラス新しい機能を入れようとしたらまず調査から
長すぎて読めない ‑> 既存ロジックを回避するようにコードを
足す ‑> さらに長くなるやばいコードの上にコードを足そうとすると、やばいコード
がどんどん増えて行く
割れ窓理論
![Page 54: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/54.jpg)
アプリのリニューアルをする過程で、aptとKotlinを導入
![Page 55: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/55.jpg)
Activityの平均行数がJavaで300行くらいkotlinで140行くらい
調査時間とかほとんどいらない
短く書く方法がある ‑> コードを短くしよう、という動機につ
ながる
割れ窓理論の解決法
短く綺麗なコードを保っている環境があれば良い
![Page 56: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/56.jpg)
すべてのヤバいコードを生まれる前に消し去りたい
![Page 57: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/57.jpg)
楽しく開発ができますように!
![Page 58: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/58.jpg)
まとめ
保守するコードが少ないと楽です
コード減量のため導入しやすい方策がaptとKotlinこれをきっかけに、チーム全員がコードを少なくすることに
積極的になったら良いですね
![Page 59: なるべくコードを書かないAndroid開発](https://reader030.vdocuments.net/reader030/viewer/2022013117/5872daa61a28ab74188b6fc7/html5/thumbnails/59.jpg)
Thank you!