なるべくコードを書かないAndroid開発
株式会社ミクシィ・株式会社Diverse
@kikuchy
Who?
 @kikuchy
菊池 紘
株式会社ミクシィ ‑‑(出向)‑‑> 株式会社Diverse
Androidの前はWebのフロントでJavaScriptとか書いてました
Shibuya.apk, Roppongi.aar, Kotlin勉強会など
おわび
Kotlinの話が20分枠に収まりきりませんでした
許可いただければお話しします
資料を後ほど公開します & 懇親会でお声掛けください
想定リスナー
二人以上で開発していて
製品のコードの保守が大変だと感じている人
「私のことかも!?」
と思った方は挙手
( ´ ▽ ̀ )ノ
コードの保守は大変!!
保守のコスト
と聞いてどんなコストを想像しますか?
人件費
保守にかける時間
気持ち的な問題
たくさん書くとそれだけ負債が増える
(›´ὼ‹ )
書かなければ良い!!!!!
人間が保守するコードを減らせば管理コ
ストは減らせる
どうするか
コンパイル時にコードを自動生成すれば、生成したコードは
管理の必要がない
ジェネレーターだけ管理していれば良い
( ´・ω・̀ )「でも新規開発じゃないと、
フレームワーク変えるとか言語変えると
か無理じゃね」
大丈夫!\ ٩( 'ω' )‫ﻭ‬ //
aptだったら一部分から使い始められる!
チームに「コードを少なくする」ことに対して前
向きになってもらおう!
apt
1. aptとは
2. 使い所
3. できること
4. 作ろう!
apt
1. aptとは
2. 使い所
3. できること
4. 作ろう!
1. aptとは
JSR269 =
Pluggable Annotation Processing API
Android界隈ではaptと呼ばれることが多いようなので 
今スライドではaptと呼びます。
コンパイル時にアノテーションを見て何かしらの処理をする仕組
み。 
ソースコードを生成することもできる。
apt
1. aptとは
2. 使い所
3. できること
4. 作ろう!
2. 使い所
マッピングの手間を減らす
何かしらの変換・対応作業
例) ButterKnife
 R.id.*  のViewをクラスのフィールドに対応させ
る
例) orma
DBの行をPOJOに、カラムをフィールドに対応さ
せる
「ライブラリにとって未知のフィールドやメソッド」へ
アクセスできる
2. 使い所
クラッシュ(ランタイムエラー)の発生をコンパイル時に前
倒しする
例)  R.java 
文字列でlayoutファイル名やIDを指定しているとtypo
の危険性が
クラッシュはユーザー体験にとって大きなマイナス
コンパイルエラーとして前倒しできればすぐミスに
気付ける
apt
1. aptとは
2. 使い所
3. できること
4. 作ろう!
3. できること
作例
POJOを HashMap<String,String> に移し替える
POJOにアノテーションをつけるだけでOK
コンパイル時に生成されるコード
POJOの各フィールドを
指定のコンバーターでStringにコンバートし
指定のkey名でHashMapにputする
@ToQueryMap
publicclassBbsCreateRequestBody{
@QueryParam(name="message",
adapter=StringTypeAdapter.class)
publicStringmessage;
@QueryParam(name="category_code",
adapter=EnumToStringTypeAdapter.class)
publicBbsCategorycategoryCode;
@QueryParam(name="title",
adapter=StringTypeAdapter.class)
publicStringtitle;
}
Serializer<BbsCreateRequestBody>serialzer=
newBbsCreateRequestBodySerializer()
Map<String,String>serialized=serialzer.serialize(request);
あなたのコーディングにどう応用できそ
うでしょうか?
apt
1. aptとは
2. 使い所
3. できること
4. 作ろう!
4. 作ろう!
rejasupotaroさんの『Androidでaptのライブラリを作る時の高速道
路』が詳しい
http://qiita.com/rejasupotaro/items/b9b89f88348222b46708
ここに書かれていない、覚えておくと便利なTipsをご紹介
(以降の話の前提)
Java Libraryの module を2つ追加
アプリから使うモジュールに、使いたいアノテーションを定義し
ておく
//RetentionをSOURCEにすると
//コンパイル後はこのアノテーションが消えてくれる
@Retention(RetentionPolicy.SOURCE)
//Targetを指定するとアノテーションできる場所を限定できる
@Target(ElementType.TYPE)
public@interfaceExampleAnnotation{
//値を持たせたかったらvalueなどを宣言する
publicintvalue();
}
コンパイル時に走るプロセッサを定義する
ソースコード以外も生成できますが、今回はソースコードを生成
//Googleの AutoServiceを使うとメタデータの生成が楽
@AutoService(Processor.class)
publicclassExampleProcessorextendsAbstractProcessor{
Filerfiler;
TypestypeUtils;
ElementselementUtils;
Messagermessager;
//プロセッサ初期化時に呼ばれる
//便利なインスタンスが渡されるので取得しておく
@Override
publicsynchronizedvoidinit(
ProcessingEnvironmentprocessingEnv){
super.init(processingEnv);
//Filer#createSourceFileにJavaソースコードをStringで渡すと
//javaファイルを作ってくれる
filer=processingEnv.getFiler();
//TypeMirrorを取得したり 具体的なTypeを取得したりできる
typeUtils=processingEnv.getTypeUtils();
//Java構文の要素から子要素を取得したりできる
elementUtils=processingEnv.getElementUtils();
//警告やエラーメッセージの出力に便利
messager=processingEnv.getMessager();
}
//このプロセッサでサポートするアノテーションを決める
@Override
publicSet<String>getSupportedAnnotationTypes(){
Set<String>types=newHashSet<>();
//アノテーションの名前はFQCNでないといけない
types.add(ExampleAnnotation.class.getCanonicalName());
returntypes;
}
Overriveしない場合、このプロセッサにつけた
 SupportedAnnotationTypes  アノテーションに書かれた型がサポート
される
@SupportedAnnotationTypes("net.kikuchy.aptsample.ExampleAnnotation")
@AutoService(Processor.class)
publicclassExampleProcessorextendsAbstractProcessor{
ソースコードの生成と書き出しには square/javapoet を使うと楽 
https://github.com/square/javapoet
//ソースコードを生成して Filterで書き出す処理を書く
@Override
publicbooleanprocess(
//今処理を要求されているアノテーション
Set<?extendsTypeElement>annotations,
//ラウンドの情報
RoundEnvironmentroundEnv){
//RoundEnvironment#getElementsAnnotatedWithを使うと
//アノテーションがついた構文要素を取得できる
for(Elementelem:
roundEnv.
getElementsAnnotatedWith(ExampleAnnotation.class)){
//ソースコードの生成と書き出し
...
}
//後続のプロセッサにアノテーションの処理を渡すか否か
returnfalse;
}
注釈処理のラウンド
 process  が何度も呼ばれる(ラウンド)
生成したソースコードに対しても注釈処理が必要なため、何
度も呼ばれる
通常は2回
 JavaFileObject#openWriter  に2回書き込もうとすると2回目は例
外が出る
Pluggable Annotation Processing API 使い方メモ 
http://qiita.com/opengl‑8080/items/beda51fe4f23750c33e9
ラウンド対策
try‑catch
2回目に出る例外を握りつぶす
プロセッサのメンバに処理済みかどうか記録しておく
ButterKnifeなどがこれ
生成したコードを使う
一度コンパイルをかければ生成される
aptプラグインを使っていれば、生成後はAndroidStudioの補
完機能でも呼び出せる
ButterKnifeのように生成コードを隠蔽する方法もある
クラスの動的ロードが必要なのでProguard設定が必要
//生成されたViewBinderクラス類は動的ロードされている
ButterKnife.bind(this);
aptの補足
aptを使ったAndroid向けライブラリ
Butter Knife
Dagger2
DeepLink Dispatcher
PermissionsDispatcher
Orma
IntentBuilder
FragmentArgs
AndroidAnnotations
kvs‑scheme
Flender
etc
Kotlin
保守コードの減量とKotlinの関係
そもそものコード行数が少なければ、保守コストも少なくて
済む
Javaは冗長になりがち、短く書ける言語を使おう
Kotlinもプロダクトの一部分から使い始められる
Java Compatible!!
もうみなさんKotlinはご存知だと思いますので 
少しだけマイナー気味で、コード短縮に効果のあることだけ紹介
します。
スコープ関数
 apply  と  let  を使うと便利なことが多いです
valintent=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
Class Delegation
Effective Javaなどで言われている「継承より合成」を圧倒的簡単
さで実現
classCustomList<E>(privatevalbase:ArrayList):List<E>bybase{
overridefunadd(elem:E){
print("${elem}isadded!")
base.add(elem)
}
}
KotlinのClass Delegationおさらい 
http://sssslide.com/speakerdeck.com/ntaro/kotlinfalseclass‑
delegationosarai‑number‑kotlin‑sansan
Property Delegation
Androidでは頻発する遅延評価が簡単に
//inActivity
privatevalhogebylazy{intent.getStringExtra("hoge")}
//KotterKnife使用
privatevaluserName:EditTextbybindView(R.id.user_name)
Delegated Properties で遊ぼう(スライド版) 
http://qiita.com/kikuchy/items/55ea0748a5850925349a
こういう話をした理由
むかーしむかし、あるところに、Activity1ファイルで4000行を超
えるソースコードがありました。
4000行超え
つらい。
その他のActivityも2000行クラス
新しい機能を入れようとしたらまず調査から
長すぎて読めない ‑> 既存ロジックを回避するようにコードを
足す ‑> さらに長くなる
やばいコードの上にコードを足そうとすると、やばいコード
がどんどん増えて行く
割れ窓理論
アプリのリニューアルをする過程で、aptとKotlinを導入
Activityの平均行数が
Javaで300行くらい
kotlinで140行くらい
調査時間とかほとんどいらない
短く書く方法がある ‑> コードを短くしよう、という動機につ
ながる
割れ窓理論の解決法
短く綺麗なコードを保っている環境があれば良い
すべてのヤバいコードを生まれる前に消し去りたい
楽しく開発ができますように!
まとめ
保守するコードが少ないと楽です
コード減量のため導入しやすい方策がaptとKotlin
これをきっかけに、チーム全員がコードを少なくすることに
積極的になったら良いですね
Thank you!

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