Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlinの言語機能をフル活用したAndroidアプリの開発

 Kotlinの言語機能をフル活用したAndroidアプリの開発

Hatena Engineer Seminar #9 で発表した内容です

E28404a128b6014e6f499d2a967c72a0?s=128

Takuji Nishibayashi

October 30, 2017
Tweet

Transcript

  1. KotlinͷݴޠػೳΛ ϑϧ׆༻ͨ͠ AndroidΞϓϦͷ։ൃ id:takuji31 Hatena Engineer Seminar #9

  2. ஫ҙࣄ߲ • AndroidΞϓϦ։ൃͷલఏ஌ࣝͱͳΔΑ͏ͳ ෦෼ͷղઆ͸͠·ͤΜ • ͜ͷεϥΠυʹॻ͔Ε͍ͯΔKotlinͷίʔυ΍ ࢓༷͸όʔδϣϯ1.1.51࣌఺ͷ΋ͷͰ͢

  3. ࣗݾ঺հ • ੢ྛ ୓ࢤ (ʹ͠͹΍͠ ͨ͘͡) • (hatena | twitter

    | github) takuji31 • גࣜձࣾ͸ͯͳ ΞϓϦέʔγϣϯΤϯδχΞ • ϒοΫϚʔΫΞϓϦνʔϜॴଐ
  4. ࣗݾ঺հ • Android։ൃ 2010೥2݄ʙ • Kotlin 2014೥12݄ʙ • iOS΍Webͷ։ൃ΋ᅂΉ

  5. ׆ಈ • Koreference • KotlinͰSharedPreferencesͷϞσϧΛ࡞Δ ϥΠϒϥϦʔ • github.com/takuji31/Koreference • Kansai.kt

    ӡӦ
  6. ϓϥΠϕʔτ • Χϝϥ(not Ϩϯζ)পॅਓ • ϚΠϘ΢ϥʔ (AVG175) • ͏͗͞ •

    ΞΠίϯ͸͏ͪͷࢠͰ͢
  7. ͱ͜ΖͰ

  8. Έͳ͞ΜAndroidΞϓϦ ։ൃͯ͠·͔͢ʁ

  9. Kotlinॻ͍ͯ·͔͢ʁ

  10. Kotlinͷݴޠػೳ׆༻ ͍ͯ͠·͔͢ʁ

  11. Null҆શ͚ͩͰຬ଍͍ͯ͠· ͤΜ͔ʁ

  12. ࠓ೔͸͸ͯͳϒοΫϚʔΫ AndroidΞϓϦͰͷKotlin ׆༻ࣄྫΛ঺հ͠·͢

  13. AGENDA • Kotlinಋೖ·ͰͷಓͷΓ • KotlinͷݴޠػೳΛ׆༻͢Δ • data class • Extension

    method / property • Delegated property
  14. Kotlin ಋೖ·ͰͷಓͷΓ

  15. ͸ͯͳͰͷ৽ٕज़ (ݴޠ΍ϛυϧ΢ΣΞ) ಋೖ

  16. ಋೖ·Ͱ • ΤϯδχΞ͕ىҊ • ΤϯδχΞνʔϑձͰಋೖͷੋඇΛٞ࿦ • CTO͕ঝೝ

  17. Kotlinͷ৔߹ • I/O Keynote͕ऴΘͬͨ௚ޙͷேɺKotlinಋೖ ىҊ (5/18) • ΤϯδχΞνʔϑձ • ঝೝ

    (5/19) • ͜͜·Ͱ͓Αͦ1೔൒
  18. Kotlin+͸ͯͳϒοΫϚʔΫͷ৔߹ • (ि໌͚ͯ) 22೔͸νʔϜͷσΟϨΫλʔ͕
 ෆࡏͩͬͨͷͰ1ճٳΈ • 23೔ேʹσΟϨΫλʔͱձ࿩ͯ͠ಋೖܾఆ • ଈ೔ಋೖ

  19. None
  20. None
  21. Kotlinͷ ݴޠػೳΛ ׆༻͢Δ

  22. data class

  23. ԿΒ͔ͷσʔλΛอ࣋͢Δͨ ΊͷΫϥε

  24. Model΍DTOΛ࡞ΔͨΊͷ ศརػೳຬࡌ

  25. ྫ) طଘͷmodelΛKotlinʹ ม׵͍ͨ͠

  26. ม׵͸Convert Java file to Kotlin fileͰ

  27. ୯७ͳม׵͚ͩͰΑ͍ͷ͔ʁ

  28. ୯७ͳม׵͚ͩͰΑ͍ͷ͔ʁ • Nullableͳͷ͔NonNullͳͷ͔ࢦఆ͍ͨ͠ • equals/hashCode/toStringΛ࣮૷͍ͨ͠

  29. ྫʣϢʔβʔͷmodelΛఆٛ • id • ໊લ • ੏ • ໊ •

    ϓϩϑΟʔϧ • ొ࿥ঢ়ଶ
  30. Javaͷmodel(Ұ෦) public class JavaUser { private final long id; private

    String firstName; private String lastName; private String profile; private boolean registered; public JavaUser(long id, String firstName, String lastName, String profile, boolean registered) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.profile = profile; this.registered = registered; } public long getId() { return id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getProfile() { return profile; } public void setProfile(String profile) { this.profile = profile; } public boolean isRegistered() { return registered; } public void setRegistered(boolean registered) { this.registered = registered; } public String getFullName() { return firstName + " " + lastName; } }
  31. ಡΊͳ͍

  32. Kotlinͷmodel data class JavaUser( val id: Long, var firstName: String,

    var lastName: String, var profile: String?, var isRegistered: Boolean = false ) { val fullName: String get() = firstName + " " + lastName } ಄ʹEBUB Λ͚ͭΔ શͯͷ CBDLJOHpFME ϓϩύςΟʔΛ DPOTUSVDUPSͰఆٛ
  33. equals/hashCode/toString →ࣗಈੜ੒

  34. boilerplate codeΛ ࡟ݮ͖ͯͬ͢͠Γ

  35. Extension

  36. ֦ுؔ਺/֦ுϓϩύςΟʔ

  37. طଘͷΫϥεʹ ؔ਺΍ϓϩύςΟʔΛੜ΍͢ (Α͏ʹݟͤΔ)࢓૊Έ

  38. FragmentΛ֦ுϓϩύςΟʔͰ ֦ு͢Δ val Fragment.baseActivity: BaseActivity?
 get() = activity as BaseActivity?


    val Fragment.actionBar: ActionBar?
 get() = baseActivity?.supportActionBar ֦ு͍ͨ͠ܕ Λॻ͘ ͦͷଞ͸௨ৗͷ ϓϩύςΟʔͱಉ͡
  39. RealmͷProviderΛ֦ுؔ਺Ͱ ֦ு͢Δ fun Provider<Realm>.getAutoCloseObservable(): Observable<Realm> { val realm = get()

    realm.use { return Observable.create { emitter -> val instance = get() emitter.setCancellable { instance.close() } emitter.onNext(instance) } } } ֦ு͍ͨ͠ܕ Λॻ͘ ͦͷଞ͸௨ৗͷ ؔ਺ͱಉ͡ (FOFSJDTͷ ܕύϥϝʔλʔ΋ࢦఆՄ
 ϓϩύςΟʔ΋ಉ༷
  40. طଘͷJavaΫϥε΋ ֦ுͰ͖Δ

  41. (Javaଆ͔Β͸) ୈ1Ҿ਺ΛϨγʔόʔʹͨ͠ staticϝιουʹݟ͑Δ

  42. → طଘΫϥεͷҰ෦Λ KotlinԽͰ͖Δ

  43. ػೳͷଟ͍ը໘Λ KotlinԽ

  44. KotlinԽͷखॱ • ֦ுؔ਺Λఆٛ͢ΔϑΝΠϧΛ࡞Δ • JavaϑΝΠϧͷϝιουΛ֦ுؔ਺ʹͯ͠Kotlinଆʹఆ ٛ • Javaͷݩϝιου͔Β֦ுؔ਺Λݺͼग़͢ • ͋Δఔ౓ݩϑΝΠϧ͕૫ͤͨΒKotlinʹม׵

    • ֦ுؔ਺ͷத਎Λݩϝιουʹ໭͍ͯ͘͠
  45. pros • 1ͭͣͭdiff͕খ͘͞ͳΔͷͰϨϏϡʔ͠΍͢ ͍ • Ұ෦͚ͩKotlinԽ͢Δ͜ͱ͕Ͱ͖ͯؾܰʹ΍Ε Δ

  46. cons • gitͷྺ࢙͕ফ໓ • ϑΝΠϧ͕෼͔ΕͯίʔυΛ௥͏ͷ͕গ͠େ มʹ

  47. ֦ு͗͢͠Δͱ Θ͚͕Θ͔Βͳ͘ͳΔ

  48. ͝ར༻͸ܭըతʹ

  49. Delegated property

  50. ҕৡϓϩύςΟʔ

  51. propertyͷॲཧΛ ผͷΦϒδΣΫτʹ ҕৡͰ͖Δ

  52. Data Binding Libraryͷ BaseObservableͷ มߋ௨஌ΛࣗಈԽ

  53. Delegated propertyͷఆٛ open class BaseObservableProperty<T : Any?>( vararg val propertyId:

    Int, var value: T ) : ReadWriteProperty<BaseObservable, T> { override fun getValue( thisRef: BaseObservable, property: KProperty<*>): T { return value } override fun setValue( thisRef: BaseObservable, property: KProperty<*>, value: T) { this.value = value propertyId.forEach(thisRef::notifyPropertyChanged) } } 3FBE8SJUF1SPQFSUZ ΠϯλʔϑΣΠεΛ࣮૷ HFU7BMVFTFU7BMVFΛ ఆٛ UIJTͷࢀরͱQSPQFSUZͷ ৘ใ͕౉͞ΕΔ
  54. Delegated propertyͷఆٛ class NonNullBaseObservableProperty<T : Any>(vararg propertyId: Int, value: T)

    : BaseObservableProperty<T>(propertyId = *propertyId, value = value) fun <T : Any?> BaseObservable.property(vararg propertyId: Int, value: T? = null) = BaseObservableProperty(propertyId = *propertyId, value = value) fun <T : Any> BaseObservable.nonNullProperty(vararg propertyId: Int, value: T) = NonNullBaseObservableProperty(propertyId = *propertyId, value = value) ܕ͕/PO/VMMͳ΋ͷ༻ͷఆٛ ֦ுؔ਺ʹ͓ͯ͘͠ͱ ࢖͏࣌ʹศར
  55. ར༻͢Δ class ViewModel: BaseObservable() { @get:Bindable var users: List<User> by

    nonNullProperty(BR.users, value = emptyList()) fun requestUsers(): Disposable { return getUser .execute() .subscribeBy( onSuccess = { user -> this.users = users }, ) } } CZͷޙʹΦϒδΣΫτΛ౉͢ TFU͢Δ͜ͱͰࣗಈతʹ OPUJGZ1SPQFSUZ$IBOHFE͕ ݺ͹ΕΔ
  56. ศརͦ͏͚ͩͲ Ͳ͏͍͏༻్Ͱ࢖͑Δ͔ Θ͔Βͳ͍ʁ

  57. SharedPreferencesͷૢ࡞

  58. ͜ΕΛ࢖͍·͠ΐ͏ˠ https://github.com/ takuji31/Koreference

  59. ͸ͯͳϒοΫϚʔΫͰ΋ ࢖͍ͬͯ·͢

  60. σϑΥϧτͷ΋ͷ΋ ༻ҙ͞Ε͍ͯ·͢

  61. σϑΥϧτͷ Delegated property(Ұ෦) • Delegates.notNull • not-null͕ͩॳظԽ࣌ʹॳظԽͰ͖ͳ͍ϓϩύςΟʔ • nullͷ··ΞΫηεͨ͠Βྫ֎ •

    lazy • ஗ԆॳظԽ • ࠷ॳͷΞΫηε࣌ʹҾ਺Ͱ౉ͨ͠ϒϩοΫͷ໭Γ஋Λฦͯ͠ Ωϟογϡ͢Δ
  62. Kotlin͸ϞμϯͳݴޠͳͷͰ ॻ͘ίʔυ΋Ϟμϯʹ ͍͖ͯ͠·͠ΐ͏ :kotlin:

  63. Enjoy Kotlin Life