Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

4,544 views

Published on

Androidオールスターズ2で発表したスライドです。
aptとkotlinのお話をさせていただきました。

Published in: Engineering
  • Be the first to comment

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

  1. 1. なるべくコードを書かないAndroid開発 株式会社ミクシィ・株式会社Diverse @kikuchy
  2. 2. Who?  @kikuchy 菊池 紘 株式会社ミクシィ ‑‑(出向)‑‑> 株式会社Diverse Androidの前はWebのフロントでJavaScriptとか書いてました Shibuya.apk, Roppongi.aar, Kotlin勉強会など
  3. 3. おわび Kotlinの話が20分枠に収まりきりませんでした 許可いただければお話しします 資料を後ほど公開します & 懇親会でお声掛けください
  4. 4. 想定リスナー 二人以上で開発していて 製品のコードの保守が大変だと感じている人
  5. 5. 「私のことかも!?」 と思った方は挙手
  6. 6. ( ´ ▽ ̀ )ノ
  7. 7. コードの保守は大変!!
  8. 8. 保守のコスト と聞いてどんなコストを想像しますか?
  9. 9. 人件費 保守にかける時間 気持ち的な問題
  10. 10. たくさん書くとそれだけ負債が増える (›´ὼ‹ )
  11. 11. 書かなければ良い!!!!!
  12. 12. 人間が保守するコードを減らせば管理コ ストは減らせる
  13. 13. どうするか コンパイル時にコードを自動生成すれば、生成したコードは 管理の必要がない ジェネレーターだけ管理していれば良い
  14. 14. ( ´・ω・̀ )「でも新規開発じゃないと、 フレームワーク変えるとか言語変えると か無理じゃね」
  15. 15. 大丈夫!\ ٩( 'ω' )‫ﻭ‬ //
  16. 16. aptだったら一部分から使い始められる! チームに「コードを少なくする」ことに対して前 向きになってもらおう!
  17. 17. apt 1. aptとは 2. 使い所 3. できること 4. 作ろう!
  18. 18. apt 1. aptとは 2. 使い所 3. できること 4. 作ろう!
  19. 19. 1. aptとは
  20. 20. JSR269 = Pluggable Annotation Processing API
  21. 21. Android界隈ではaptと呼ばれることが多いようなので  今スライドではaptと呼びます。
  22. 22. コンパイル時にアノテーションを見て何かしらの処理をする仕組 み。  ソースコードを生成することもできる。
  23. 23. apt 1. aptとは 2. 使い所 3. できること 4. 作ろう!
  24. 24. 2. 使い所 マッピングの手間を減らす 何かしらの変換・対応作業 例) ButterKnife  R.id.*  のViewをクラスのフィールドに対応させ る 例) orma DBの行をPOJOに、カラムをフィールドに対応さ せる 「ライブラリにとって未知のフィールドやメソッド」へ アクセスできる
  25. 25. 2. 使い所 クラッシュ(ランタイムエラー)の発生をコンパイル時に前 倒しする 例)  R.java  文字列でlayoutファイル名やIDを指定しているとtypo の危険性が クラッシュはユーザー体験にとって大きなマイナス コンパイルエラーとして前倒しできればすぐミスに 気付ける
  26. 26. apt 1. aptとは 2. 使い所 3. できること 4. 作ろう!
  27. 27. 3. できること 作例 POJOを HashMap<String,String> に移し替える POJOにアノテーションをつけるだけでOK コンパイル時に生成されるコード POJOの各フィールドを 指定のコンバーターでStringにコンバートし 指定のkey名でHashMapにputする
  28. 28. @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);
  29. 29. あなたのコーディングにどう応用できそ うでしょうか?
  30. 30. apt 1. aptとは 2. 使い所 3. できること 4. 作ろう!
  31. 31. 4. 作ろう! rejasupotaroさんの『Androidでaptのライブラリを作る時の高速道 路』が詳しい http://qiita.com/rejasupotaro/items/b9b89f88348222b46708 ここに書かれていない、覚えておくと便利なTipsをご紹介
  32. 32. (以降の話の前提) Java Libraryの module を2つ追加
  33. 33. アプリから使うモジュールに、使いたいアノテーションを定義し ておく //RetentionをSOURCEにすると //コンパイル後はこのアノテーションが消えてくれる @Retention(RetentionPolicy.SOURCE) //Targetを指定するとアノテーションできる場所を限定できる @Target(ElementType.TYPE) public@interfaceExampleAnnotation{ //値を持たせたかったらvalueなどを宣言する publicintvalue(); }
  34. 34. コンパイル時に走るプロセッサを定義する ソースコード以外も生成できますが、今回はソースコードを生成 //Googleの AutoServiceを使うとメタデータの生成が楽 @AutoService(Processor.class) publicclassExampleProcessorextendsAbstractProcessor{ Filerfiler; TypestypeUtils; ElementselementUtils; Messagermessager;
  35. 35. //プロセッサ初期化時に呼ばれる //便利なインスタンスが渡されるので取得しておく @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(); }
  36. 36. //このプロセッサでサポートするアノテーションを決める @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{
  37. 37. ソースコードの生成と書き出しには square/javapoet を使うと楽  https://github.com/square/javapoet //ソースコードを生成して Filterで書き出す処理を書く @Override publicbooleanprocess( //今処理を要求されているアノテーション Set<?extendsTypeElement>annotations, //ラウンドの情報 RoundEnvironmentroundEnv){ //RoundEnvironment#getElementsAnnotatedWithを使うと //アノテーションがついた構文要素を取得できる for(Elementelem: roundEnv. getElementsAnnotatedWith(ExampleAnnotation.class)){ //ソースコードの生成と書き出し ... } //後続のプロセッサにアノテーションの処理を渡すか否か returnfalse; }
  38. 38. 注釈処理のラウンド  process  が何度も呼ばれる(ラウンド) 生成したソースコードに対しても注釈処理が必要なため、何 度も呼ばれる 通常は2回  JavaFileObject#openWriter  に2回書き込もうとすると2回目は例 外が出る Pluggable Annotation Processing API 使い方メモ  http://qiita.com/opengl‑8080/items/beda51fe4f23750c33e9
  39. 39. ラウンド対策 try‑catch 2回目に出る例外を握りつぶす プロセッサのメンバに処理済みかどうか記録しておく ButterKnifeなどがこれ
  40. 40. 生成したコードを使う 一度コンパイルをかければ生成される aptプラグインを使っていれば、生成後はAndroidStudioの補 完機能でも呼び出せる ButterKnifeのように生成コードを隠蔽する方法もある クラスの動的ロードが必要なのでProguard設定が必要 //生成されたViewBinderクラス類は動的ロードされている ButterKnife.bind(this);
  41. 41. aptの補足
  42. 42. aptを使ったAndroid向けライブラリ Butter Knife Dagger2 DeepLink Dispatcher PermissionsDispatcher Orma IntentBuilder FragmentArgs AndroidAnnotations kvs‑scheme Flender etc
  43. 43. Kotlin
  44. 44. 保守コードの減量とKotlinの関係 そもそものコード行数が少なければ、保守コストも少なくて 済む Javaは冗長になりがち、短く書ける言語を使おう Kotlinもプロダクトの一部分から使い始められる Java Compatible!!
  45. 45. もうみなさんKotlinはご存知だと思いますので  少しだけマイナー気味で、コード短縮に効果のあることだけ紹介 します。
  46. 46. スコープ関数  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
  47. 47. 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
  48. 48. Property Delegation Androidでは頻発する遅延評価が簡単に //inActivity privatevalhogebylazy{intent.getStringExtra("hoge")} //KotterKnife使用 privatevaluserName:EditTextbybindView(R.id.user_name) Delegated Properties で遊ぼう(スライド版)  http://qiita.com/kikuchy/items/55ea0748a5850925349a
  49. 49. こういう話をした理由
  50. 50. むかーしむかし、あるところに、Activity1ファイルで4000行を超 えるソースコードがありました。
  51. 51. 4000行超え
  52. 52. つらい。
  53. 53. その他のActivityも2000行クラス 新しい機能を入れようとしたらまず調査から 長すぎて読めない ‑> 既存ロジックを回避するようにコードを 足す ‑> さらに長くなる やばいコードの上にコードを足そうとすると、やばいコード がどんどん増えて行く 割れ窓理論
  54. 54. アプリのリニューアルをする過程で、aptとKotlinを導入
  55. 55. Activityの平均行数が Javaで300行くらい kotlinで140行くらい 調査時間とかほとんどいらない 短く書く方法がある ‑> コードを短くしよう、という動機につ ながる 割れ窓理論の解決法 短く綺麗なコードを保っている環境があれば良い
  56. 56. すべてのヤバいコードを生まれる前に消し去りたい
  57. 57. 楽しく開発ができますように!
  58. 58. まとめ 保守するコードが少ないと楽です コード減量のため導入しやすい方策がaptとKotlin これをきっかけに、チーム全員がコードを少なくすることに 積極的になったら良いですね
  59. 59. Thank you!

×