なるべくコードを書かないandroid開発

59

Upload: hiroshi-kikuchi

Post on 16-Apr-2017

3.482 views

Category:

Engineering


11 download

TRANSCRIPT

Page 1: なるべくコードを書かないAndroid開発

なるべくコードを書かないAndroid開発

株式会社ミクシィ・株式会社Diverse

@kikuchy

Page 2: なるべくコードを書かないAndroid開発

Who?

 @kikuchy菊池 紘株式会社ミクシィ ‑‑(出向)‑‑> 株式会社DiverseAndroidの前はWebのフロントでJavaScriptとか書いてましたShibuya.apk, Roppongi.aar, Kotlin勉強会など

Page 3: なるべくコードを書かないAndroid開発

おわび

Kotlinの話が20分枠に収まりきりませんでした

許可いただければお話しします

資料を後ほど公開します & 懇親会でお声掛けください

Page 4: なるべくコードを書かないAndroid開発

想定リスナー

二人以上で開発していて

製品のコードの保守が大変だと感じている人

Page 5: なるべくコードを書かないAndroid開発

「私のことかも!?」

と思った方は挙手

Page 6: なるべくコードを書かないAndroid開発

( ´ ▽  )ノ

Page 7: なるべくコードを書かないAndroid開発

コードの保守は大変!!

Page 8: なるべくコードを書かないAndroid開発

保守のコスト

と聞いてどんなコストを想像しますか?

Page 9: なるべくコードを書かないAndroid開発

人件費

保守にかける時間

気持ち的な問題

Page 10: なるべくコードを書かないAndroid開発

たくさん書くとそれだけ負債が増える(›´ω‹ )

Page 11: なるべくコードを書かないAndroid開発

書かなければ良い!!!!!

Page 12: なるべくコードを書かないAndroid開発

人間が保守するコードを減らせば管理コストは減らせる

Page 13: なるべくコードを書かないAndroid開発

どうするか

コンパイル時にコードを自動生成すれば、生成したコードは管理の必要がない

ジェネレーターだけ管理していれば良い

Page 14: なるべくコードを書かないAndroid開発

( ´・ω・ )「でも新規開発じゃないと、フレームワーク変えるとか言語変えるとか無理じゃね」

Page 15: なるべくコードを書かないAndroid開発

大丈夫!\\ ٩( 'ω' )و //

Page 16: なるべくコードを書かないAndroid開発

aptだったら一部分から使い始められる!

チームに「コードを少なくする」ことに対して前向きになってもらおう!

Page 17: なるべくコードを書かないAndroid開発

apt1. aptとは2. 使い所3. できること4. 作ろう!

Page 18: なるべくコードを書かないAndroid開発

apt1. aptとは2. 使い所3. できること4. 作ろう!

Page 19: なるべくコードを書かないAndroid開発

1. aptとは

Page 20: なるべくコードを書かないAndroid開発

JSR269 =

Pluggable Annotation Processing API

Page 21: なるべくコードを書かないAndroid開発

Android界隈ではaptと呼ばれることが多いようなので 今スライドではaptと呼びます。

Page 22: なるべくコードを書かないAndroid開発

コンパイル時にアノテーションを見て何かしらの処理をする仕組

み。 ソースコードを生成することもできる。

Page 23: なるべくコードを書かないAndroid開発

apt1. aptとは2. 使い所3. できること4. 作ろう!

Page 24: なるべくコードを書かないAndroid開発

2. 使い所マッピングの手間を減らす

何かしらの変換・対応作業

例) ButterKnife R.id.*  のViewをクラスのフィールドに対応させ

例) ormaDBの行をPOJOに、カラムをフィールドに対応さ

せる

「ライブラリにとって未知のフィールドやメソッド」へ

アクセスできる

Page 25: なるべくコードを書かないAndroid開発

2. 使い所クラッシュ(ランタイムエラー)の発生をコンパイル時に前

倒しする

例)  R.java 文字列でlayoutファイル名やIDを指定しているとtypoの危険性が

クラッシュはユーザー体験にとって大きなマイナス

コンパイルエラーとして前倒しできればすぐミスに

気付ける

Page 26: なるべくコードを書かないAndroid開発

apt1. aptとは2. 使い所3. できること4. 作ろう!

Page 27: なるべくコードを書かないAndroid開発

3. できること作例

POJOを HashMap<String, String> に移し替えるPOJOにアノテーションをつけるだけでOKコンパイル時に生成されるコード

POJOの各フィールドを

指定のコンバーターでStringにコンバートし

指定のkey名でHashMapにputする

Page 28: なるべくコードを書かないAndroid開発

@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開発

あなたのコーディングにどう応用できそうでしょうか?

Page 30: なるべくコードを書かないAndroid開発

apt1. aptとは2. 使い所3. できること4. 作ろう!

Page 31: なるべくコードを書かないAndroid開発

4. 作ろう!

rejasupotaroさんの『Androidでaptのライブラリを作る時の高速道路』が詳しい

http://qiita.com/rejasupotaro/items/b9b89f88348222b46708

ここに書かれていない、覚えておくと便利なTipsをご紹介

Page 32: なるべくコードを書かないAndroid開発

(以降の話の前提)

Java Libraryの module を2つ追加

Page 33: なるべくコードを書かないAndroid開発

アプリから使うモジュールに、使いたいアノテーションを定義し

ておく

// RetentionをSOURCEにすると // コンパイル後はこのアノテーションが消えてくれる @Retention(RetentionPolicy.SOURCE)

// Targetを指定するとアノテーションできる場所を限定できる @Target(ElementType.TYPE) public @interface ExampleAnnotation {

// 値を持たせたかったらvalueなどを宣言する public int value(); }

Page 34: なるべくコードを書かないAndroid開発

コンパイル時に走るプロセッサを定義する

ソースコード以外も生成できますが、今回はソースコードを生成

// Google の AutoService を使うとメタデータの生成が楽 @AutoService(Processor.class) public class ExampleProcessor extends AbstractProcessor { Filer filer; Types typeUtils; Elements elementUtils; Messager messager;

Page 35: なるべくコードを書かないAndroid開発

// プロセッサ初期化時に呼ばれる // 便利なインスタンスが渡されるので取得しておく @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開発

// このプロセッサでサポートするアノテーションを決める @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開発

ソースコードの生成と書き出しには 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開発

注釈処理のラウンド

 process  が何度も呼ばれる(ラウンド)

生成したソースコードに対しても注釈処理が必要なため、何

度も呼ばれる

通常は2回 JavaFileObject#openWriter  に2回書き込もうとすると2回目は例外が出る

Pluggable Annotation Processing API 使い方メモ http://qiita.com/opengl‑8080/items/beda51fe4f23750c33e9

Page 39: なるべくコードを書かないAndroid開発

ラウンド対策

try‑catch2回目に出る例外を握りつぶす

プロセッサのメンバに処理済みかどうか記録しておく

ButterKnifeなどがこれ

Page 40: なるべくコードを書かないAndroid開発

生成したコードを使う

一度コンパイルをかければ生成される

aptプラグインを使っていれば、生成後はAndroidStudioの補完機能でも呼び出せる

ButterKnifeのように生成コードを隠蔽する方法もある

クラスの動的ロードが必要なのでProguard設定が必要

// 生成されたViewBinderクラス類は動的ロードされている ButterKnife.bind(this);

Page 41: なるべくコードを書かないAndroid開発

aptの補足

Page 43: なるべくコードを書かないAndroid開発

Kotlin

Page 44: なるべくコードを書かないAndroid開発

保守コードの減量とKotlinの関係

そもそものコード行数が少なければ、保守コストも少なくて済む

Javaは冗長になりがち、短く書ける言語を使おう

Kotlinもプロダクトの一部分から使い始められる

Java Compatible!!

Page 45: なるべくコードを書かないAndroid開発

もうみなさんKotlinはご存知だと思いますので 少しだけマイナー気味で、コード短縮に効果のあることだけ紹介

します。

Page 46: なるべくコードを書かないAndroid開発

スコープ関数

 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開発

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開発

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開発

こういう話をした理由

Page 50: なるべくコードを書かないAndroid開発

むかーしむかし、あるところに、Activity1ファイルで4000行を超えるソースコードがありました。

Page 51: なるべくコードを書かないAndroid開発

4000行超え

Page 52: なるべくコードを書かないAndroid開発

つらい。

Page 53: なるべくコードを書かないAndroid開発

その他のActivityも2000行クラス新しい機能を入れようとしたらまず調査から

長すぎて読めない ‑> 既存ロジックを回避するようにコードを

足す ‑> さらに長くなるやばいコードの上にコードを足そうとすると、やばいコード

がどんどん増えて行く

割れ窓理論

Page 54: なるべくコードを書かないAndroid開発

アプリのリニューアルをする過程で、aptとKotlinを導入

Page 55: なるべくコードを書かないAndroid開発

Activityの平均行数がJavaで300行くらいkotlinで140行くらい

調査時間とかほとんどいらない

短く書く方法がある ‑> コードを短くしよう、という動機につ

ながる

割れ窓理論の解決法

短く綺麗なコードを保っている環境があれば良い

Page 56: なるべくコードを書かないAndroid開発

すべてのヤバいコードを生まれる前に消し去りたい

Page 57: なるべくコードを書かないAndroid開発

楽しく開発ができますように!

Page 58: なるべくコードを書かないAndroid開発

まとめ

保守するコードが少ないと楽です

コード減量のため導入しやすい方策がaptとKotlinこれをきっかけに、チーム全員がコードを少なくすることに

積極的になったら良いですね

Page 59: なるべくコードを書かないAndroid開発

Thank you!