Slide 1

Slide 1 text

既存のAndroidプロジェクトに   Kotlinを導⼊入した話 #DroidKaigi  #DroidKaigiB   Jumpei  Yamamoto

Slide 2

Slide 2 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > ⾃自⼰己紹介 - ⼭山本純平   - Sansan株式会社  Eight事業部     - EightのAndroidアプリの開発   - twitter:  @boohbah   - github:  https://github.com/yamamotoj

Slide 3

Slide 3 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 3

Slide 4

Slide 4 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 4 第2回  Kotlin勉強会@Sansan   3/23  開催決定!!

Slide 5

Slide 5 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > お話すること Sansan社のEightアプリでの開発事例例を元 に、Kotlinを既存のJavaのプロジェクトへの 導⼊入する際に学んできたことをお話します。

Slide 6

Slide 6 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > アジェンダ - Eightの紹介   - 弊社アプリでのKotlin導⼊入の経緯、実記録   - 使ってよかったところ   - ⼤大変だったこと   - Java環境と上⼿手に共存するためのTips

Slide 7

Slide 7 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 7

Slide 8

Slide 8 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 8 2015年年  Google  Play  Storeの   ベストアプリに選ばれました!   (2年年連続)

Slide 9

Slide 9 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > Eight  Androidアプリ - 2012年年から継続的に開発   - 2週間  〜~  1ヶ⽉月のスパンで新機能リリース   - 2015年年8⽉月よりKotlin導⼊入   - アプリ内のKotlin⽐比率率率は約15% Files Total  Lines Java 429 68527 Kotlin 140 10687

Slide 10

Slide 10 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > 導⼊入の経緯

Slide 11

Slide 11 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > 導⼊入のきっかけ - 前職はiOS開発でSwiftメイン   - そもそもにJavaのコードに不不満   > ボイラープレートが多い   > Null安全でない   > 型推論論されない   > RxJavaとかで無名クラスつらい   - プロジェクトメンバがすでにkotlinを使い始めていた

Slide 12

Slide 12 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > 初コミット - サンプル実装のプロジェクトで試験導⼊入   -  Java  -‐‑‒>  Kotlinの変換   - 導⼊入時に増加するapkのサイズは823KB(1.0.0現在) public  class  SampleClass  {
        private  String  name;
        public  String  getName(){
                return  name;
        }
 } class  SampleClass  {
        val  name:  String?  =  null
 }  

Slide 13

Slide 13 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 13 9⽉月 10⽉月 11⽉月 12⽉月 1⽉月 2⽉月 2015年年 2016年年 m13 m14 β1 β2 β3 β4 RC 1.0 • Kotlin初コミット(8/27) • 2回⽬目のコミット  (10/5) • 初めてのActivity  (10/20) • 本格的なKotlin化  (11/M) • 新規コードはすべてKotlin 1ヶ⽉月ほど寝かす ⼿手を付け始めてから軌道に乗るまで  2-‐‑‒  2.5ヶ⽉月

Slide 14

Slide 14 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > 導⼊入しはじめのメンバーの反応 - はじめはKotlinに及び腰   - ついつい慣れたJavaで書いてしまう   - レビューに時間がかかる はじめは厳しいけど   射撃しつつ前進!!

Slide 15

Slide 15 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > 導⼊入の推進⼒力力 - 個⼈人の興味   > 魅⼒力力に気づくと早い   > m13でsealed  class導⼊入でやる気になった   - レビューによる知識識の共有   > Kotlinの便便利利な機能を知る  -‐‑‒>  さらにKotlinに興味がでてくる   - iOSエンジニアからも受けがよい   > SwiftににているのでiOSエンジニアでもレビューしやすい   > 実装の知⾒見見をAndroid  /  iOSで共有出来る

Slide 16

Slide 16 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > 良良かった点

Slide 17

Slide 17 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 17 Java Ave.  160lines  /  File

Slide 18

Slide 18 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 18 Kotlin Ave.  76lines  /  File

Slide 19

Slide 19 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 19 圧倒的な効率率率と安全性

Slide 20

Slide 20 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > コードレビューが効率率率的 - 作りこむ機能に対してコード量量が少ない   - ボイラープレートが少ないので、コード上の読むべき箇所 がわかりやすい   - コード上の匂いのする場所が浮き彫りになりやすくなる   > なぜvarを使っているのか?   > Single  expressionで書けないメソッドは?   > !!を使っている箇所

Slide 21

Slide 21 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > ハマりどころ

Slide 22

Slide 22 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > バージョンアップに関わる問題 - ある程度度メジャーなバージョンアップ直後は問題が起こる ことが多かった   > 0.13.1513  <-‐‑‒  アプリが起動できない重⼤大な問題     > 0.13.1514  <-‐‑‒  直後にマイナーバージョンアップ   - いきなりProguardでエラーが発⽣生

Slide 23

Slide 23 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. Kotterknife   Kotlin   1.0.0  beta1 Kotlin   1.0.0  beta1 > SNAPSHOTバージョン指定の問題 - バージョンにSNAPSHOT 指定されている場合、同じ バージョンでも異異なるライ ブラリがリリース可能。   - 取得する側では常に最新の ライブラリを取得する。 compile  'com.jakewharton:kotterknife:0.1.0-­‐SNAPSHOT' Kotlin   1.0.0  beta2 My   Application   Kotlin   1.0.0  beta1 Kotlin   1.0.0  beta2 ⾃自動的に   ダウンロード Զ͸·ͩ όʔδϣϯΞοϓ ͨ͘͠ͳ͍Μͩʔʂ

Slide 24

Slide 24 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. JVM  /  Androidライブラリの特定 のコミットを取得して、jarをビ ルドして配布してくれるサービス dependencies  {          compile  'com.github.JakeWharton:kotterknife:36ae6d5ecb'   }   allprojects  {       repositories  {         ...         maven  {  url  "https://jitpack.io"  }       }     }

Slide 25

Slide 25 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 25

Slide 26

Slide 26 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > ハマったライブラリ

Slide 27

Slide 27 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > kotterknife class  MainActivity  :  AppCompatActivity()  {          val  textView:  TextView  by  bindView(R.id.textView)          override  fun  onCreate(savedInstanceState:  Bundle?)  {                  super.onCreate(savedInstanceState)                  setContentView(R.layout.activity_main)          }   } Jake  Wharton⽒氏作成のview  injectionライブラリ   Kotlin版  Butter  Knife

Slide 28

Slide 28 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > Fragmentでは class  MyFragment  :  Fragment()  {          val  textView:  TextView  by  bindView(R.id.textView)          override  fun  onCreate(savedInstanceState:  Bundle?)  {                  super.onCreate(savedInstanceState)                  retainInstance  =  true          }          override  fun  onCreateView(                          inflater:  LayoutInflater?,                          container:  ViewGroup?,                          savedInstanceState:  Bundle?):  View?  {                  return  inflater?.inflate(R.layout.fragment_main,  container,  false);          }   }   retainInstance  =  true   にすると画⾯面が回転した時には   Fragmentインスタンスは開放されずに   Viewが再⽣生成される Viewが再⽣生成され ても、再⽣生成前の Viewが残る

Slide 29

Slide 29 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > Kotter  knifeではissue登録済み https://github.com/JakeWharton/kotterknife/issues/5

Slide 30

Slide 30 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > kapt - Kotlin  Annotation  Processing  Tool   - Kotlin上でPluggable  Annotation  Processing  API  (JSR  269)  を 使って実装されたライブラリを使う際に必要となる   - Kotlinのソースに付与されたアノテーションを解釈する   - KotlinからAnnotationで⽣生成されたコードを参照できるようにする   - DataBindingライブラリとの相性が悪く導⼊入できていない   - いまのところAnnotationで⽣生成されたクラスへの参照はJavaから しか参照できない

Slide 31

Slide 31 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > JavaとKotlinの共存

Slide 32

Slide 32 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > Kotlinは100%Java互換 - KotlinのコードはすべてJavaから参照することができる。   - JavaのコードもKotlinから参照することができる。   - KotlinのコードをJavaから参照するときに使えるアノテー ション   > @JvnStatic   > @JvmField   > @File:JvmName(“name”)   > @JvmOverrides

Slide 33

Slide 33 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > @JvmField class  Bar  {          val  name  =  “name”          @JvmField  val  password  =  “password”          companion  object{                val  staticName  =  "name"                  @JvmField  val  staticPassword  =  "password"          }   } //Java   Bar  bar  =  new  Bar();   String  name  =  bar.getName();   String  password  =  bar.password;   String  staticName  =  Bar.Companion.getStaticName()   String  staticPassword  =  Bar.staticPassword

Slide 34

Slide 34 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > Parcelable class  MyParcelable(val  name:  String)  {   }

Slide 35

Slide 35 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > Parcelable class  MyParcelable(val  name:  String)  :  Parcelable  {          protected  constructor(src:  Parcel)  :  this(src.readString())          override  fun  describeContents():  Int  =  0          override  fun  writeToParcel(dest:  Parcel,  flags:  Int)  {                  dest.writeString(name)          }          companion  object  {                  val  CREATOR:  Parcelable.Creator  =                                  object  :  Parcelable.Creator  {                                          override  fun  createFromParcel(`in`:  Parcel):  MyParcelable  {                                                  return  MyParcelable(`in`)                                          }                                          override  fun  newArray(size:  Int):  Array  {                                                  return  arrayOfNulls(size)                                          }                                  }          }   } @JvmField このままだとJavaからは   MyParcelable.Companion.CREATER   と⾒見見えてしまう

Slide 36

Slide 36 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > @file:JvmName() //  KotlinExtensions.kt   @file:JvmName("StringUtil")
 
 fun  String.prepend(str:String)  =  str  +  this   “Kotlin”.prepend(“Hello!  ”)  //  -­‐>  Hello!  Kotlin //  Java   StringUtil.prepend("Kotlin",  "Hello!  “);   //  >  Hello!  Kotlin

Slide 37

Slide 37 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > Null安全とJava

Slide 38

Slide 38 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > Null  safety val  nullable:  String?  =  null  //  NullΛ୅ೖ͢Δ͜ͱ͕ Ͱ͖Δ   val  nonNull:  String  =  “string”  //  NullΛ୅ೖͰ͖ͳ͍   val  nonNull:  String  =  null  //  ίϯύΠϧΤϥʔ notNullなパラメータにnullを代⼊入しようとすると   コンパイルエラー

Slide 39

Slide 39 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > Kotlin関連のcrash原因トップ Parameter  specified  as  non-‐‑‒null  is  null;   non-‐‑‒nullで指定された変数がnull

Slide 40

Slide 40 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > 実はJavaから渡された変数 //  Java   public  class  Hoge  {          public  String  getString()  {                  return  null;          }   } String!は   StringとしてもString?としても参照できる

Slide 41

Slide 41 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > @Nullable  /  @NotNull  アノテーション //  Kotlin   val  hoge  =  Hoge()   val  s0:String?  =  hoge.nullable   val  s2:String  =  hoge.nullable //  Java   public  class  Hoge  {          @NonNull          public  String  getString()  {                  return  "hoge";          }          @Nullable          public  String  getNullable()  {                  return  null;          }   }   @Nullableアノテーションをつける ことでKotlinからNonNullなプロパ ティで受けようとするとコンパイ ルエラー

Slide 42

Slide 42 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > ただし Javaでは@NonNullアノテーションをつけたプロパティがnullを返して も、静的チェックに引っかかるだけで、エラーにはならないので注意。 //  Java   public  class  Hoge  {          @NonNull          public  String  getString()  {                  return  null;          }   }

Slide 43

Slide 43 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. > まとめ - 祝Kotlin  1.0.0!   - ⼤大変だったことのほとんどはバージョンアップに伴う問題 だった。   - 今Javaのプロジェクトをやっている⼈人でも安⼼心してKotlin を導⼊入できる

Slide 44

Slide 44 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 44 企業ブースでお待ちしています。

Slide 45

Slide 45 text

Copyright  ©  Sansan,  Inc.  All  rights  reserved. 45 Enjoy!