KotlinのDelegated Propertiesを活用してAndroidアプリ開発をもっと便利にする

KotlinのDelegated Propertiesを活用してAndroidアプリ開発をもっと便利にする

Kotlinには委譲プロパティ(Delegetaed proprties)という仕組みがあります。
標準ライブラリのlazyや、AndroidXのActivityやFragmentに実装されているviewModelなどで普段からあまり意識せずに利用している方も多いと思います。
本セッションでは、標準ライブラリに含まれている委譲プロパティ、および拙作のライブラリであるKotprefなどの事例を交えながら、委譲プロパティの仕組み、Kotlinでの実現方法、活用事例や自作する際の方法などをお話します。

本セッションに含まれる内容
- KotlinのDelegated Propertiesとは
- Delegated Propertiesの仕組み
- 標準ライブラリで提供されるDelegated Properties
- 作って見ることでより深く理解する
- Tips

6b7fa48f32e52512924ff44597d9881f?s=128

chibatching

March 17, 2020
Tweet

Transcript

  1. ,PUMJOͷ%FMFHBUFE1SPQFSUJFTΛ ׆༻ͯ͠"OESPJEΞϓϦ։ൃΛ ΋ͬͱศརʹ͢Δ !%F/"BQL ઍ༿ོ༤ εϚʔτλΫγʔࣄۀ෦γεςϜ։ൃ෦ גࣜձࣾσΟʔɾΤψɾΤʔ

  2. ࣗݾ঺հ • ઍ༿ོ༤!DIJCBUDIJOH • גࣜձࣾσΟʔɾΤψɾΤʔ • εϚʔτλΫγʔࣄۀ෦γεςϜ։ൃ෦ • .07৐຿һΞϓϦͷ։ൃ •

    DIJCBUDIJOH,PUQSFG
  3. ໨࣍ ,PUMJOͷ%FMFHBUFE1SPQFSUJFTͱ͸ %FMFHBUFE1SPQFSUJFTͷ࢓૊Έ ඪ४ϥΠϒϥϦͰఏڙ͞ΕΔ%FMFHBUFE1SPQFSUJFT ࡞ͬͯݟΔ͜ͱͰΑΓਂ͘ཧղ͢Δ 5JQT

  4. %FMFHBUFE1SPQFSUJFTͱ͸

  5. %FMFHBUFE1SPQFSUJFTͱ͸ • ϓϩύςΟͷHFUTFUॲཧΛଞͷΫϥεΦϒδΣΫτʹ ҕৡ͢Δ͜ͱ͕Ͱ͖Δ࢓૊Έ • CZΩʔϫʔυͰҕৡઌΛࢦఆ͢Δ

  6. %FMFHBUFE1SPQFSUJFTͱ͸ class DelegateSample { var myProp: String by MyDelegate() var

    someProp: String by someDelegate() private fun someDelegate() = SomeDelegate() }
  7. %FMFHBUFE1SPQFSUJFTͱ͸ class DelegateSample { var myProp: String by MyDelegate() var

    someProp: String by someDelegate() private fun someDelegate() = SomeDelegate() } CZͷޙʹҕৡઌͷ ΦϒδΣΫτΛࢦఆ͢Δ
  8. %FMFHBUFE1SPQFSUJFTͱ͸ class DelegateSample { var myProp: String by MyDelegate() var

    someProp: String by someDelegate() private fun someDelegate() = SomeDelegate() } ҕৡઌΦϒδΣΫτΛ औಘ͢Δؔ਺౳Ͱ΋Մ
  9. %FMFHBUFE1SPQFSUJFTͱ͸ • CZΩʔϫʔυͰࢦఆͨ͠%FMFHBUFE1SPQFSUZ͸ ,PUMJOͰͲͷΑ͏ʹղऍ͞ΕΔͷ͔

  10. %FMFHBUFE1SPQFSUJFTͱ͸ class DelegateSample { var myProp: String by MyDelegate() }

  11. %FMFHBUFE1SPQFSUJFTͱ͸ class DelegateSample { private val myProp$delegate = MyDelegate() var

    myProp: String get() = myProp$delegate.getValue(this, this::myProp) set(value: String) = myProp$delegate.setValue(this, this::myProp, value) }
  12. %FMFHBUFE1SPQFSUJFTͱ͸ class DelegateSample { private val myProp$delegate = MyDelegate() var

    myProp: String get() = myProp$delegate.getValue(this, this::myProp) set(value: String) = myProp$delegate.setValue(this, this::myProp, value) } ҕৡઌͷΦϒδΣΫτΛQSJWBUFͳ ϓϩύςΟͱͯ͠อ࣋
  13. %FMFHBUFE1SPQFSUJFTͱ͸ class DelegateSample { private val myProp$delegate = MyDelegate() var

    myProp: String get() = myProp$delegate.getValue(this, this::myProp) set(value: String) = myProp$delegate.setValue(this, this::myProp, value) } ҕৡઌΦϒδΣΫτ͕ HFUͷॲཧΛ͢Δ
  14. %FMFHBUFE1SPQFSUJFTͱ͸ class DelegateSample { private val myProp$delegate = MyDelegate() var

    myProp: String get() = myProp$delegate.getValue(this, this::myProp) set(value: String) = myProp$delegate.setValue(this, this::myProp, value) } ಉ༷ʹҕৡઌΦϒδΣΫτ͕ TFUͷॲཧΛ͢Δ
  15. %FMFHBUFE1SPQFSUJFTͱ͸ • ৄࡉͳ࢓૊Έ΍࣮૷ํ๏͸ޙ൒ʹ

  16. ඪ४ϥΠϒϥϦͰఏڙ͞ΕΔ %FMFHBUFE1SPQFSUJFT

  17. TUEMJCͷ%FMFHBUFE1SPQFSUJFT • MB[Z • %FMFHBUFTOPU/VMM  • %FMFHBUFTPCTFSWBCMFWFUPBCMF • 4UPSJOH1SPQFSUJFTJOB.BQ

  18. MB[Z

  19. MB[Z • ϓϩύςΟͷॳظԽΛ࠷ॳͷࢀর·Ͱ஗Ԇ val lazyProperty: String by lazy { "initialized

    at ${System.currentTimeMillis()}" }
  20. MB[Z • ϓϩύςΟͷॳظԽΛ࠷ॳͷࢀর·Ͱ஗Ԇ val lazyProperty: String by lazy { "initialized

    at ${System.currentTimeMillis()}" } println(System.currentTimeMillis()) // 1581485501007 delay(500)
  21. MB[Z • ϓϩύςΟͷॳظԽΛ࠷ॳͷࢀর·Ͱ஗Ԇ val lazyProperty: String by lazy { "initialized

    at ${System.currentTimeMillis()}" } println(System.currentTimeMillis()) // 1581485501007 delay(500) println(lazyProperty) // initialized at 1581485501514 ࠷ॳͷࢀর࣌ʹϒϩοΫ͕࣮ߦ͞Ε ϓϩύςΟ͕ॳظԽ͞ΕΔ NT
  22. MB[Z • ϓϩύςΟͷॳظԽΛ࠷ॳͷࢀর·Ͱ஗Ԇ val lazyProperty: String by lazy { "initialized

    at ${System.currentTimeMillis()}" } println(System.currentTimeMillis()) // 1581485501007 delay(500) println(lazyProperty) // initialized at 1581485501514 delay(500) println(lazyProperty)
  23. MB[Z • ϓϩύςΟͷॳظԽΛ࠷ॳͷࢀর·Ͱ஗Ԇ val lazyProperty: String by lazy { "initialized

    at ${System.currentTimeMillis()}" } println(System.currentTimeMillis()) // 1581485501007 delay(500) println(lazyProperty) // initialized at 1581485501514 delay(500) println(lazyProperty) // initialized at 1581485501514 ճ໨Ҏ߱ͷΞΫηεͰ͸࠷ॳʹ ࣮ߦͨ͠ͱ͖ͷ஋ʹͳΔ NT
  24. MB[Z • "OESPJEͰ͸ΫϥεͷΠϯελϯεੜ੒࣌ʹ͸ ΞΫηεͰ͖ͳ͍΋ͷ͕ଟ͍ • ྫ "DUJWJUZͷPO$SFBUFҎ߱ʹΞΫηεՄೳͳ΋ͷ • $POUFYU •

    *OUFOU • FUDʜ
  25. MB[Z • +BWB෩ͳΞϓϩʔν private var param: String? = null

  26. MB[Z • +BWB෩ͳΞϓϩʔν private var param: String? = null override

    fun onCreate(savedInstanceState: Bundle?) { param = intent.getStringExtra("param") Log.d(TAG, param) }
  27. MB[Z • +BWB෩ͳΞϓϩʔν private var param: String? = null override

    fun onCreate(savedInstanceState: Bundle?) { param = intent.getStringExtra("param") ?: throw IllegalArgumentException() Log.d(TAG, param) }
  28. MB[Z • +BWB෩ͳΞϓϩʔν private var param: String? = null override

    fun onCreate(savedInstanceState: Bundle?) { param = intent.getStringExtra("param") ?: throw IllegalArgumentException() Log.d(TAG, param) }
  29. MB[Z • +BWB෩ͳΞϓϩʔν private var param: String? = null override

    fun onCreate(savedInstanceState: Bundle?) { param = intent.getStringExtra("param") ?: throw IllegalArgumentException() Log.d(TAG, param) }
  30. MB[Z • +BWB෩ͳΞϓϩʔν private var param: String? = null override

    fun onCreate(savedInstanceState: Bundle?) { param = intent.getStringExtra("param") ?: throw IllegalArgumentException() Log.d(TAG, param!!) } OVMMBCMFͳͷͰOPOOVMM΁ͷ ม׵͕ඞཁʹͳΔ
  31. MB[Z • MBUFJOJUΛ࢖ͬͨํ๏ private lateinit var param: String override fun

    onCreate(savedInstanceState: Bundle?) { param = intent.getStringExtra("param") ?: throw IllegalArgumentException() Log.d(TAG, param) }
  32. MB[Z • MBUFJOJUΛ࢖ͬͨํ๏ private lateinit var param: String override fun

    onCreate(savedInstanceState: Bundle?) { param = intent.getStringExtra("param") ?: throw IllegalArgumentException() Log.d(TAG, param) }
  33. MB[Z • MBUFJOJUΛ࢖ͬͨํ๏ private lateinit var param: String override fun

    onCreate(savedInstanceState: Bundle?) { param = intent.getStringExtra("param") ?: throw IllegalArgumentException() Log.d(TAG, param) } private fun someOperation() { param = "overwritten with wrong value" } NVUBCMFͳͷͰ༧ظ͠ͳ͍ ஋ͷॻ͖׵͕͑ൃੜ͠͏Δ
  34. MB[Z • MBUFJOJUΛ࢖ͬͨํ๏ private lateinit var param: String override fun

    onCreate(savedInstanceState: Bundle?) { param = intent.getStringExtra("param") ?: throw IllegalArgumentException() Log.d(TAG, param) } private fun someOperation() { if (!::param.isInitialized) { param = intent.getStringExtra("param") } textView.text = param } ෳ਺ͷՕॴ͔Βࢀর͞ΕΔ৔߹ɺ ॳظԽ͞Ε͍ͯΔ͜ͱΛ֬ೝ͢Δ ඞཁ͕͋Δ৔߹΋ʜ
  35. MB[Z • MB[ZͳΒJNNVUBCMFͳϓϩύςΟͰ஗ԆॳظԽͰ͖Δ private val param: String by lazy {

    intent.getStringExtra("param") ?: throw IllegalArgumentException() } override fun onCreate(savedInstanceState: Bundle?) { Log.d(TAG, param) }
  36. %FMFHBUFTOPU/VMM

  37. %FMFHBUFTOPU/VMM • MBUFJOJU  private var param: String by Delegates.notNull()

    override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) param = intent.getStringExtra("param") ?: throw IllegalArgumentException() Log.d(TAG, param) }
  38. %FMFHBUFTOPU/VMM • MBUFJOJU͸ϓϦϛςΟϒܕʹ͸࢖༻Ͱ͖ͳ͍

  39. %FMFHBUFTOPU/VMM • MBUFJOJUͷར༻Ͱ͖ͳ͍ϓϦϛςΟϒܕʹ • MBUFJOJU͸୯ͳΔϑΟʔϧυ͕ͩEFMFHBUJPO͸ϓϩύςΟຖ ʹΦϒδΣΫτΛ࣋ͭ͜ͱʹͳΔͷͰద੾ʹ࢖͍෼͚Λ • ௚઀ϑΟʔϧυΛ࣋ͨͳ͍ͷͰ+BWBͱͷޓ׵ੑʹ஫ҙ

  40. %FMFHBUFTOPU/VMM • +BWBͱͷޓ׵ੑʹ஫ҙ class Sample { var notNull by Delegates.notNull<String>()

    lateinit var lateinitVar: String }
  41. %FMFHBUFTOPU/VMM • +BWBͱͷޓ׵ੑʹ஫ҙ public final class Sample { @NotNull private

    final ReadWriteProperty notNull$delegate; @NotNull public String lateinitVar; public final void setNotNull(@NotNull String var1) {} @NotNull public final String getNotNull() {} public final void setLateinitVar(@NotNull String var1) {} @NotNull public final String getLateinitVar() {} }
  42. %FMFHBUFTOPU/VMM • +BWBͱͷޓ׵ੑʹ஫ҙ public final class Sample { @NotNull private

    final ReadWriteProperty notNull$delegate; @NotNull public String lateinitVar; public final void setNotNull(@NotNull String var1) {} @NotNull public final String getNotNull() {} public final void setLateinitVar(@NotNull String var1) {} @NotNull public final String getLateinitVar() {} } QVCMJD͔ͭະॳظԽͷ ϑΟʔϧυͱͯ࣋ͭ͠
  43. %FMFHBUFTOPU/VMM • +BWBͱͷޓ׵ੑʹ஫ҙ public final class Sample { @NotNull private

    final ReadWriteProperty notNull$delegate; @NotNull public String lateinitVar; public final void setNotNull(@NotNull String var1) {} @NotNull public final String getNotNull() {} public final void setLateinitVar(@NotNull String var1) {} @NotNull public final String getLateinitVar() {} } QSJWBUF͔ͭGJOBMͰϓϩύςΟΛ ௚઀ϑΟʔϧυͱͯ࣋ͨ͠ͳ͍
  44. %FMFHBUFTOPU/VMM • +BWBͱͷޓ׵ੑͰ஫ҙ͢Δ఺ MBUFJOJUͱͷҧ͍  • ϑΟʔϧυ͕QSJWBUFGJOBM • ܕ͕ҕৡઌΦϒδΣΫτͷܕ

  45. %FMFHBUFTOPU/VMM • +BWBͱͷޓ׵ੑͰ஫ҙ͢Δ఺ MBUFJOJUͱͷҧ͍  • ϑΟʔϧυ͕QSJWBUFGJOBM • ܕ͕ҕৡઌΦϒδΣΫτͷܕ •

    %BHHFSͷϑΟʔϧυ*OKFDUJPO͕Ͱ͖ͳ͍ʂ
  46. %FMFHBUFTOPU/VMM class Sample { var notNull by Delegates.notNull<String>() lateinit var

    lateinitVar: String }
  47. %FMFHBUFTOPU/VMM class Sample { @Inject var notNull by Delegates.notNull<String>() @Inject

    lateinit var lateinitVar: String }
  48. %FMFHBUFTOPU/VMM public final class Sample { @NotNull @Inject private final

    ReadWriteProperty notNull$delegate; @NotNull @Inject public String lateinitVar; public final void setNotNull(@NotNull String var1) {} public final String getNotNull() {} public final void setLateinitVar(@NotNull String var1) {} public final String getLateinitVar() {} }
  49. %FMFHBUFTOPU/VMM public final class Sample { @NotNull @Inject private final

    ReadWriteProperty notNull$delegate; @NotNull @Inject public String lateinitVar; public final void setNotNull(@NotNull String var1) {} public final String getNotNull() {} public final void setLateinitVar(@NotNull String var1) {} public final String getLateinitVar() {} }
  50. %FMFHBUFTOPU/VMM public final class Sample { @NotNull @Inject private final

    ReadWriteProperty notNull$delegate; @NotNull @Inject public String lateinitVar; public final void setNotNull(@NotNull String var1) {} public final String getNotNull() {} public final void setLateinitVar(@NotNull String var1) {} public final String getLateinitVar() {} } ϑΟʔϧυ*OKFDUJPOͰ͖ͳ͍
  51. %FMFHBUFTOPU/VMM • %BHHFS͸ηολʔ*OKFDUJPO΋αϙʔτ͍ͯ͠Δ • OPU/VMM ʹݶΒͣ%FMFHBUFE1SPQFSUZʹ *OKFDU͍ͨ͠৔߹͸ͪ͜ΒΛ࢖͏

  52. %FMFHBUFTOPU/VMM class Sample { @Inject var notNull by Delegates.notNull<String>() }

  53. %FMFHBUFTOPU/VMM class Sample { @Inject var notNull by Delegates.notNull<String>() }

  54. %FMFHBUFTOPU/VMM class Sample { @set:Inject var notNull by Delegates.notNull<String>() }

  55. %FMFHBUFTOPU/VMM public final class Sample { @NotNull @Inject private final

    ReadWriteProperty notNull$delegate; public final void setNotNull(@NotNull String var1) {} public final String getNotNull() {} }
  56. %FMFHBUFTOPU/VMM public final class Sample { @NotNull private final ReadWriteProperty

    notNull$delegate; @Inject public final void setNotNull(@NotNull String var1) {} public final String getNotNull() {} }
  57. %FMFHBUFTPCTFSWBCMFWFUPBCMF

  58. %FMFHBUFTPCTFSWBCMFWFUPBCMF • PCTFSWBCMF • มߋΛݕ஌ͯ͠ॲཧΛ࣮ߦͰ͖Δ • WFUPBCMF • มߋલʹมߋ಺༰Λड͚ೖΕΔ͔൑ఆͰ͖Δ

  59. %FMFHBUFTPCTFSWBCMFWFUPBCMF var inputtedText: String by Delegates.observable("init") { property, old, new

    -> println("inputted $inputtedText") } var positiveNumber: Long by Delegates.vetoable(1L) { property, old, new -> new > 0L }
  60. %FMFHBUFTPCTFSWBCMFWFUPBCMF var inputtedText: String by Delegates.observable("init") { property, old, new

    -> println("inputted $inputtedText") } var positiveNumber: Long by Delegates.vetoable(1L) { property, old, new -> new > 0L } ஋ͷ୅ೖޙʹϒϩοΫͷॲཧΛ࣮ߦ
  61. %FMFHBUFTPCTFSWBCMFWFUPBCMF var inputtedText: String by Delegates.observable("init") { property, old, new

    -> println("inputted $inputtedText") } var positiveNumber: Long by Delegates.vetoable(1L) { property, old, new -> new > 0L } ஋ͷ୅ೖલʹϒϩοΫΛ࣮ߦ͠ USVFΛฦͨ͠ͱ͖ͷΈ୅ೖ͕ߦΘΕΔ
  62. 4UPSJOH1SPQFSUJFTJOB.BQ

  63. 4UPSJOH1SPQFSUJFTJOB.BQ • LFZ͕4USJOHͷ.BQ͔ΒϓϩύςΟ໊Ͱ ஋ΛಡΈग़͢͜ͱ͕Ͱ͖Δ

  64. 4UPSJOH1SPQFSUJFTJOB.BQ class User(map: Map<String, Any>) { val name: String by

    map val age: Int by map }
  65. 4UPSJOH1SPQFSUJFTJOB.BQ class User(map: Map<String, Any>) { val name: String by

    map val age: Int by map } Ωʔ͕4USJOHͷ.BQΛ ҕৡઌʹࢦఆ͢Δ
  66. 4UPSJOH1SPQFSUJFTJOB.BQ class User(map: Map<String, Any>) { val name: String by

    map val age: Int by map } val user = User( mapOf( "name" to "chibatching", "age" to 34 ) ) Ωʔ͕ϓϩύςΟ໊ͱ Ұக͢ΔΑ͏ͳ.BQΛ౉͢
  67. 4UPSJOH1SPQFSUJFTJOB.BQ class User(map: Map<String, Any>) { val name: String by

    map val age: Int by map } val user = User( mapOf( "name" to "chibatching", "age" to 34 ) ) println("name: ${user.name}, age: ${user.age}") // name: chibatching, age: 34
  68. 4UPSJOH1SPQFSUJFTJOB.BQ class User(map: Map<String, Any>) { val name: String by

    map val age: Int by map } val user = User( mapOf( "name" to "chibatching", "age" to 34 ) )
  69. 4UPSJOH1SPQFSUJFTJOB.BQ class User(map: MutableMap<String, Any>) { var name: String by

    map var age: Int by map } val user = User( mutableMapOf( "name" to "chibatching", "age" to 34 ) )
  70. 4UPSJOH1SPQFSUJFTJOB.BQ class User(map: MutableMap<String, Any>) { var name: String by

    map var age: Int by map } val user = User( mutableMapOf( "user" to "chibatching", "age" to 34 ) ) user.name = "chibatching Jr" user.age = 4 // {name=chibatching Jr, age=4}
  71. TUEMJCͷ%FMFHBUFE1SPQFSUJFT • MB[Z • %FMFHBUFTOPU/VMM  • %FMFHBUFTPCTFSWBCMFWFUPBCMF • 4UPSJOH1SPQFSUJFTJOB.BQ

  72. %FMFHBUFE1SPQFSUJFTΛ ࡞ͬͯΈΔ

  73. ͳʹΛ%FMFHBUFE1SPQFSUJFTʹ͢Δ͔ • ڞ௨Խ͍ͨ͠TFUHFUॲཧ • TUEMJCʹ༻ҙ͞Ε͍ͯΔΑ͏ͳ΋ͷ • ΦϒδΣΫτ͔Βͷ஋औΓग़͠΍อଘʹ ఆܕతͳखଓ͖͕ඞཁͳ΋ͷ • "OESPJE97JFX.PEFMͷऔಘ

  74. %FMFHBUFE1SPQFSUJFTʹ͢Δ΂͖Ͱͳ͍΋ͷ • ࣌ؒͷ͔͔Δॲཧɺ*0ॲཧͳͲ࣮ߦεϨουΛ ҙࣝ͢Δඞཁ͕͋ΔΑ͏ͳ΋ͷ • ݟͨ໨͸ϓϩύςΟ΁ͷΞΫηε • ར༻ऀ͸ॏ͍ͨॲཧ͕ߦΘΕΔ͜ͱΛ૝૾͢Δͷ͕ ೉͍͠

  75. 4IBSFE1SFGFSFODFTͷಡΈॻ͖Λ ؆୯ʹ͢Δ1SFGFSFODF%FMFHBUF

  76. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE)

  77. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE)

  78. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE)  $POUFYU

  79. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE)  $POUFYU

  80. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE)  $POUFYUϑΝΠϧ໊

  81. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE)  $POUFYUϑΝΠϧ໊

  82. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE) pref.edit().putString("name", "chibatching").apply()  $POUFYUϑΝΠϧ໊

  83. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE) pref.edit().putString("name", "chibatching").apply()  $POUFYUϑΝΠϧ໊

    1SFGFSFODFͷΩʔ
  84. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE) pref.edit().putString("name", "chibatching").apply()  $POUFYUϑΝΠϧ໊

    1SFGFSFODFͷΩʔ
  85. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE) pref.edit().putString("name", "chibatching").apply() pref.getString("name", "default")

     $POUFYUϑΝΠϧ໊ 1SFGFSFODFͷΩʔ
  86. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE) pref.edit().putString("name", "chibatching").apply() pref.getString("name", "default")

     $POUFYUϑΝΠϧ໊ 1SFGFSFODFͷΩʔ
  87. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE) pref.edit().putString("name", "chibatching").apply() pref.getString("name", "default")

     $POUFYUϑΝΠϧ໊ 1SFGFSFODFͷΩʔσϑΥϧτ஋
  88. Կ͕ඞཁʁ val pref = context.getSharedPreferences("user_settings", Context.MODE_PRIVATE) pref.edit().putString("name", "chibatching").apply() pref.getString("name", "default")

     $POUFYUϑΝΠϧ໊ 1SFGFSFODFͷΩʔσϑΥϧτ஋
  89. • $POUFYU • ϑΝΠϧ໊ • 1SFGFSFODFΩʔ • σϑΥϧτ஋ Կ͕ඞཁʁ

  90. %FMFHBUFE1SPQFSUJFTͷجຊ • ҕৡઌΦϒδΣΫτͷ࠷௿৚݅ • HFU7BMVFΦϖϨʔλ͕࣮૷͞Ε͍ͯΔ͜ͱ • NVUBCMFͳϓϩύςΟͷ৔߹͸ TFU7BMVFΦϖϨʔλ͕࣮૷͞Ε͍ͯΔ͜ͱ

  91. %FMFHBUFE1SPQFSUJFTͷجຊ class PreferenceDelegate { operator fun getValue( thisRef: Any?, property:

    KProperty<*>): String { return "delegated value" } operator fun setValue( thisRef: Any?, property: KProperty<*>, value: String) { } }
  92. %FMFHBUFE1SPQFSUJFTͷجຊ class PreferenceDelegate { operator fun getValue( thisRef: Any?, property:

    KProperty<*>): String { return "delegated value" } operator fun setValue( thisRef: Any?, property: KProperty<*>, value: String) { } } HFU7BMVFʹ͸ HFUUFSͷॲཧΛ࣮૷͢Δ
  93. %FMFHBUFE1SPQFSUJFTͷجຊ class PreferenceDelegate { operator fun getValue( thisRef: Any?, property:

    KProperty<*>): String { return "delegated value" } operator fun setValue( thisRef: Any?, property: KProperty<*>, value: String) { } } TFU7BMVFʹ͸ TFUUFSͷॲཧΛ࣮૷͢Δ
  94. %FMFHBUFE1SPQFSUJFTͷجຊ class PreferenceDelegate { operator fun getValue( thisRef: Any?, property:

    KProperty<*>): String { return "delegated value" } operator fun setValue( thisRef: Any?, property: KProperty<*>, value: String) { } }
  95. %FMFHBUFE1SPQFSUJFTͷجຊ class PreferenceDelegate : ReadWriteProperty<Any?, String> { operator fun getValue(

    thisRef: Any?, property: KProperty<*>): String { return "delegated value" } operator fun setValue( thisRef: Any?, property: KProperty<*>, value: String) { } } NVUBCMF3FBE8SJUF1SPQFSUZ JNNVUBCMF3FBE0OMZ1SPQFSUZ
  96. %FMFHBUFE1SPQFSUJFTͷجຊ class PreferenceDelegate : ReadWriteProperty<Any?, String> { override operator fun

    getValue( thisRef: Any?, property: KProperty<*>): String { return "delegated value" } override operator fun setValue( thisRef: Any?, property: KProperty<*>, value: String) { } }
  97. %FMFHBUFE1SPQFSUJFTͷجຊ class PreferenceDelegate : ReadWriteProperty<Any?, String> { override operator fun

    getValue( thisRef: Any?, property: KProperty<*>): String { return "delegated value" } override operator fun setValue( thisRef: Any?, property: KProperty<*>, value: String) { } }
  98. %FMFHBUFE1SPQFSUJFTͷجຊ • ҕৡઌΦϒδΣΫτͷ࠷௿৚݅ • HFU7BMVFΦϖϨʔλ͕࣮૷͞Ε͍ͯΔ͜ͱ • NVUBCMFͳϓϩύςΟͷ৔߹͸ TFU7BMVFΦϖϨʔλ͕࣮૷͞Ε͍ͯΔ͜ͱ • 3FBE8SJUF1SPQFSUZ

    3FBE0OMZ1SPQFSUZΠϯλʔϑΣʔε Λ࣮૷͢Δͱ*%&Ͱิ׬͕Ͱָ͖ͯ
  99. • ͱΓ͋͑ͣඞཁͳ΋ͷΛશͯίϯετϥΫλʹ • $POUFYU • ϑΝΠϧ໊ • 1SFGFSFODFΩʔ • σϑΥϧτ஋

    1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ
  100. class PreferenceDelegate( fileName: String, context: Context, private val key: String,

    private val default: String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(key, default)!! } 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ
  101. class PreferenceDelegate( fileName: String, context: Context, private val key: String,

    private val default: String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(key, default)!! } 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ
  102. class PreferenceDelegate( fileName: String, context: Context, private val key: String,

    private val default: String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(key, default)!! } 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ
  103. • ར༻͢ΔଆΛݟͯΈΔ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  104. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class MainActivity : AppCompatActivity() { private var userName: String

    by PreferenceDelegate("user_settings", this, "user_name", "") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<TextView>(R.id.user_name).text = userName findViewById<Button>(R.id.save_button).setOnClickListener { userName = findViewById<EditText>(R.id.input).text.toString() } }
  105. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class MainActivity : AppCompatActivity() { private var userName: String

    by PreferenceDelegate("user_settings", this, "user_name", "") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<TextView>(R.id.user_name).text = userName findViewById<Button>(R.id.save_button).setOnClickListener { userName = findViewById<EditText>(R.id.input).text.toString() } }
  106. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class MainActivity : AppCompatActivity() { private var userName: String

    by PreferenceDelegate("user_settings", this, "user_name", "") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<TextView>(R.id.user_name).text = userName findViewById<Button>(R.id.save_button).setOnClickListener { userName = findViewById<EditText>(R.id.input).text.toString() } }
  107. • ΋͏গָ͠ʹ͍ͨ͠ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ private var userName: String by PreferenceDelegate("user_settings", this,

    "user_name", "")
  108. • ΋͏গָ͠ʹ͍ͨ͠ • ϓϩύςΟ໊ΩʔʹͰ͖ΔͱָʹͳΓͦ͏ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ private var userName: String by

    PreferenceDelegate("user_settings", this, "user_name", "")
  109. • 4IBSFE1SFGFSFODFTͷΩʔʹϓϩύςΟ໊Λ࢖͍͍ͨ • %FMFHBUFE1SPQFSUZ͔ΒϓϩύςΟͷ৘ใΛ஌Γ͍ͨ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  110. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val key:

    String, private val default: String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(key, default)!! }
  111. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val key:

    String, private val default: String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(key, default)!! }
  112. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val key:

    String, private val default: String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(key, default)!! } Ҿ਺ͷ,1SPQFSUZ͸ ҕৡݩϓϩύςΟ
  113. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val key:

    String, private val default: String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(key, default)!! }
  114. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val key:

    String, private val default: String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(property.name, default)!! }
  115. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val key:

    String, private val default: String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(property.name, default)!! }
  116. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val default:

    String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(property.name, default)!! }
  117. • ϓϩύςΟͷ৘ใ͸,1SPQFSUZ͔ΒऔಘͰ͖Δ • ͞·͟·ͳ৘ใ͕औಘՄೳ • OBNF • PQFOGJOBM • FUD

    • OBNFҎ֎ͷ৘ใ͸LPUMJOSFGMFDUύοέʔδ͕ඞཁ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ
  118. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class MainActivity : AppCompatActivity() { private var userName: String

    by PreferenceDelegate("user_settings", this, "user_name", "") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<TextView>(R.id.user_name).text = userName findViewById<Button>(R.id.save_button).setOnClickListener { userName = findViewById<EditText>(R.id.input).text.toString() } }
  119. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class MainActivity : AppCompatActivity() { private var userName: String

    by PreferenceDelegate("user_settings", this, "") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<TextView>(R.id.user_name).text = userName findViewById<Button>(R.id.save_button).setOnClickListener { userName = findViewById<EditText>(R.id.input).text.toString() } }
  120. • ΞϓϦશମͰ࢖͑ΔΑ͏ผͷΫϥεʹ੾Γग़͍ͨ͠ • ϓϩύςΟ໊΍ϑΝΠϧ໊Λ 5ZQP͢Δͱਖ਼͘͠஋͕औಘอଘͰ͖ͳ͍ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ private var userName: String

    by PreferenceDelegate("user_settings", this, "")
  121. • ผͷΫϥεʹ੾Γग़͢ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { private val fileName

    = "user_settings" var userName by PreferenceDelegate(fileName, context, "") }
  122. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class MainActivity : AppCompatActivity() { private var userName: String

    by PreferenceDelegate("user_settings", this, "") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<TextView>(R.id.user_name).text = userName findViewById<Button>(R.id.save_button).setOnClickListener { userName = findViewById<EditText>(R.id.input).text.toString() } }
  123. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class MainActivity : AppCompatActivity() { private val userSettings by

    lazy { UserSettings(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<TextView>(R.id.user_name).text = userName findViewById<Button>(R.id.save_button).setOnClickListener { userName = findViewById<EditText>(R.id.input).text.toString() } }
  124. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class MainActivity : AppCompatActivity() { private val userSettings by

    lazy { UserSettings(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<TextView>(R.id.user_name).text = userName findViewById<Button>(R.id.save_button).setOnClickListener { userName = findViewById<EditText>(R.id.input).text.toString() } }
  125. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class MainActivity : AppCompatActivity() { private val userSettings by

    lazy { UserSettings(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) findViewById<TextView>(R.id.user_name).text = userSettings.userName findViewById<Button>(R.id.save_button).setOnClickListener { userSettings.userName = findViewById<EditText>(R.id.input).text.toString() } }
  126. • ผͷΫϥεʹ੾Γग़͕ͨ͠ʜ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { private val fileName

    = "user_settings" var userName by PreferenceDelegate(fileName, context, "") }
  127. • ϓϩύςΟ͕૿͑Δͱʜ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { private val fileName

    = "user_settings" var userName by PreferenceDelegate(fileName, context, "") var iconUrl by PreferenceDelegate(fileName, context, "") var coverPhoto by PreferenceDelegate(fileName, context, "") }
  128. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { private val fileName = "user_settings"

    var userName by PreferenceDelegate(fileName, context, "") var iconUrl by PreferenceDelegate(fileName, context, "") var coverPhoto by PreferenceDelegate(fileName, context, "") }
  129. • Ϋϥε໊Λͦͷ··ϑΝΠϧ໊ʹͯ͠΋Αͦ͞͏ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { private val fileName

    = "user_settings" var userName by PreferenceDelegate(fileName, context, "") var iconUrl by PreferenceDelegate(fileName, context, "") var coverPhoto by PreferenceDelegate(fileName, context, "") }
  130. • ϑΝΠϧ໊ΛϓϩύςΟ͕એݴ͞Ε͍ͯΔΫϥε໊ ͔Βઃఆ͍ͨ͠ • %FMFHBUFE1SPQFSUZ͔ΒϓϩύςΟ͕ એݴ͞Ε͍ͯΔΫϥεͷ͜ͱΛ஌Γ͍ͨ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  131. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val default:

    String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(property.name, default)!! }
  132. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val default:

    String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(property.name, default)!! } ϓϩύςΟ͕એݴ͞Ε͍ͯΔ ΫϥεΠϯελϯε
  133. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val default:

    String ) : ReadWriteProperty<Any?, String> { private val preference = context.getSharedPreferences(fileName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(property.name, default)!! }
  134. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val default:

    String ) : ReadWriteProperty<Any?, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(property.name, default)!! }
  135. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val default:

    String ) : ReadWriteProperty<Any?, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { return preference.getString(property.name, default)!! }
  136. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val default:

    String ) : ReadWriteProperty<Any?, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  137. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( fileName: String, context: Context, private val default:

    String ) : ReadWriteProperty<Any?, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  138. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( context: Context, private val default: String )

    : ReadWriteProperty<Any?, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  139. • HFU7BMVFTFU7BMVFͷύϥϝʔλUIJT3FG͸ ϓϩύςΟΛએݴ͍ͯ͠ΔΫϥεΠϯελϯε 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  140. • ϑΝΠϧ໊ΛলུͰ͖ΔΑ͏ʹͳͬͨ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { private val fileName

    = "user_settings" var userName by PreferenceDelegate(fileName, context, "") var iconUrl by PreferenceDelegate(fileName, context, "") var coverPhoto by PreferenceDelegate(fileName, context, "") }
  141. • ϑΝΠϧ໊ΛলུͰ͖ΔΑ͏ʹͳͬͨ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { var userName by

    PreferenceDelegate(context, "") var iconUrl by PreferenceDelegate(context, "") var coverPhoto by PreferenceDelegate(context, "") }
  142. • $POUFYU΋লུͰ͖Δͱخ͍͠ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { var userName by

    PreferenceDelegate(context, "") var iconUrl by PreferenceDelegate(context, "") var coverPhoto by PreferenceDelegate(context, "") }
  143. • HFU7BMVFTFU7BMVFͷύϥϝʔλUIJT3FG͸ ϓϩύςΟΛએݴ͍ͯ͠ΔΫϥεΠϯελϯε 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  144. • HFU7BMVFTFU7BMVFͷύϥϝʔλUIJT3FG͸ ϓϩύςΟΛએݴ͍ͯ͠ΔΫϥεΠϯελϯε • UIJT3FG͕DPOUFYUΛอ͍࣋ͯ͠Ε͹UIJT3FG͔Β औಘͰ͖ΔͷͰ͸ʁ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  145. • HFU7BMVFTFU7BMVFͷύϥϝʔλUIJT3FG͸ ϓϩύςΟΛએݴ͍ͯ͠ΔΫϥεΠϯελϯε • UIJT3FG͕DPOUFYUΛอ͍࣋ͯ͠Ε͹UIJT3FG͔Β औಘͰ͖ΔͷͰ͸ʁ • ܕʮ"OZ ʯ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  146. • HFU7BMVFTFU7BMVFͷύϥϝʔλUIJT3FG͸ ϓϩύςΟΛએݴ͍ͯ͠ΔΫϥεΠϯελϯε • UIJT3FG͕DPOUFYUΛอ͍࣋ͯ͠Ε͹UIJT3FG͔Β औಘͰ͖ΔͷͰ͸ʁ • ܕʮ"OZ ʯ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  147. • UIJT3FGͷܕ͸੍ݶ͢Δ͜ͱ͕Մೳ • ಛఆͷΫϥε಺ͰͷΈར༻Ͱ͖Δ%FMFHBUF͕࣮૷Ͱ͖Δ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  148. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { var userName by PreferenceDelegate(context, "")

    var iconUrl by PreferenceDelegate(context, "") var coverPhoto by PreferenceDelegate(context, "") }
  149. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(context: Context) { var userName by PreferenceDelegate(context, "")

    var iconUrl by PreferenceDelegate(context, "") var coverPhoto by PreferenceDelegate(context, "") } interface PreferenceModel { val context: Context }
  150. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(override val context: Context) : PreferenceModel { var

    userName by PreferenceDelegate(context, "") var iconUrl by PreferenceDelegate(context, "") var coverPhoto by PreferenceDelegate(context, "") } interface PreferenceModel { val context: Context }
  151. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( context: Context, private val default: String )

    : ReadWriteProperty<Any?, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  152. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( context: Context, private val default: String )

    : ReadWriteProperty<Any?, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: Any?, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  153. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( context: Context, private val default: String )

    : ReadWriteProperty<PreferenceModel, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! } ܕΛࢦఆ͢Δ͜ͱͰ ಛఆͷΫϥε಺ͰͷΈ࢖͑ΔΑ͏ ੍ݶ͢Δ͜ͱ͕Ͱ͖Δ
  154. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( context: Context, private val default: String )

    : ReadWriteProperty<PreferenceModel, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  155. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( context: Context, private val default: String )

    : ReadWriteProperty<PreferenceModel, String> { private fun getPreferenceForClass(thisRef: Any?) = context.getSharedPreferences( thisRef?.javaClass?.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  156. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( context: Context, private val default: String )

    : ReadWriteProperty<PreferenceModel, String> { private fun getPreferenceForClass(thisRef: PreferenceModel) = thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  157. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( context: Context, private val default: String )

    : ReadWriteProperty<PreferenceModel, String> { private fun getPreferenceForClass(thisRef: PreferenceModel) = thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  158. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( private val default: String ) : ReadWriteProperty<PreferenceModel,

    String> { private fun getPreferenceForClass(thisRef: PreferenceModel) = thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  159. • ϓϩύςΟͷఆ͕͖ٛͬ͢Γͱ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(override val context: Context) : PreferenceModel

    { var userName by PreferenceDelegate("") var iconUrl by PreferenceDelegate("") var coverPhoto by PreferenceDelegate("") }
  160. • ར༻ଆ͸͖ͬ͢ΓͱͰ͖͕ͨ%FMFHBUFଆͰ͸ʜ • ౎౓4IBSFE1SFGFSFODFTΛऔಘ͍ͯ͠Δͷ͕ؾʹͳΔ • ϑΝΠϧ໊΍Ωʔ͸มΘΒͳ͍ͷͰຊ౰͸ ίϯετϥΫλͰઃఆ͍ͨ͠ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  161. • QSPWJEF%FMFHBUFΦϖϨʔλΛ࢖͏͜ͱͰ %FMFHBUFEQSPQFSUZJFTͷόΠϯυ࣌ʹॲཧΛߦ͑Δ • 4JODF,PUMJO 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  162. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( private val default: String ) : ReadWriteProperty<PreferenceModel,

    String> { private fun getPreferenceForClass(thisRef: PreferenceModel) = thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  163. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( private val default: String ) : ReadWriteProperty<PreferenceModel,

    String> { private fun getPreferenceForClass(thisRef: PreferenceModel) = thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(property.name, default)!! }
  164. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( private val key: String, private val default:

    String ) : ReadWriteProperty<PreferenceModel, String> { private fun getPreferenceForClass(thisRef: PreferenceModel) = thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(key, default)!! }
  165. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( private val preference: SharedPreferences, private val key:

    String, private val default: String ) : ReadWriteProperty<PreferenceModel, String> { private fun getPreferenceForClass(thisRef: PreferenceModel) = thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(key, default)!! }
  166. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( private val preference: SharedPreferences, private val key:

    String, private val default: String ) : ReadWriteProperty<PreferenceModel, String> { private fun getPreferenceForClass(thisRef: PreferenceModel) = thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE) override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { val preference = getPreferenceForClass(thisRef) return preference.getString(key, default)!! }
  167. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceDelegate( private val preference: SharedPreferences, private val key:

    String, private val default: String ) : ReadWriteProperty<PreferenceModel, String> { override operator fun getValue( thisRef: PreferenceModel, property: KProperty<*> ): String { return preference.getString(key, default)!! }
  168. • QSPWJEF%FMFHBUFͰҕৡઌΫϥεΛఏڙ͢ΔΫϥεΛ࣮૷ 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ

  169. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceLoader(private val default: String) { operator fun provideDelegate(

    thisRef: PreferenceModel, property: KProperty<*> ): ReadWriteProperty<PreferenceModel, String> { return PreferenceDelegate( thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE ), property.name, default ) } }
  170. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceLoader(private val default: String) { operator fun provideDelegate(

    thisRef: PreferenceModel, property: KProperty<*> ): ReadWriteProperty<PreferenceModel, String> { return PreferenceDelegate( thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE ), property.name, default ) } }
  171. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceLoader(private val default: String) { operator fun provideDelegate(

    thisRef: PreferenceModel, property: KProperty<*> ): ReadWriteProperty<PreferenceModel, String> { return PreferenceDelegate( thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE ), property.name, default ) } }
  172. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceLoader(private val default: String) { operator fun provideDelegate(

    thisRef: PreferenceModel, property: KProperty<*> ): ReadWriteProperty<PreferenceModel, String> { return PreferenceDelegate( thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE ), property.name, default ) } }
  173. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceLoader(private val default: String) { operator fun provideDelegate(

    thisRef: PreferenceModel, property: KProperty<*> ): ReadWriteProperty<PreferenceModel, String> { return PreferenceDelegate( thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE ), property.name, default ) } }
  174. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceLoader(private val default: String) { operator fun provideDelegate(

    thisRef: PreferenceModel, property: KProperty<*> ): ReadWriteProperty<PreferenceModel, String> { return PreferenceDelegate( thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE ), property.name, default ) } }
  175. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceLoader(private val default: String) { operator fun provideDelegate(

    thisRef: PreferenceModel, property: KProperty<*> ): ReadWriteProperty<PreferenceModel, String> { return PreferenceDelegate( thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE ), property.name, default ) } }
  176. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceLoader(private val default: String) { operator fun provideDelegate(

    thisRef: PreferenceModel, property: KProperty<*> ): ReadWriteProperty<PreferenceModel, String> { return PreferenceDelegate( thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE ), property.name, default ) } }
  177. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class PreferenceLoader(private val default: String) { operator fun provideDelegate(

    thisRef: PreferenceModel, property: KProperty<*> ): ReadWriteProperty<PreferenceModel, String> { return PreferenceDelegate( thisRef.context.getSharedPreferences( thisRef.javaClass.simpleName, Context.MODE_PRIVATE ), property.name, default ) } }
  178. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(override val context: Context) : PreferenceModel { var

    userName by PreferenceDelegate("") var iconUrl by PreferenceDelegate("") var coverPhoto by PreferenceDelegate("") }
  179. 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ class UserSettings(override val context: Context) : PreferenceModel { var

    userName by PreferenceLoader("") var iconUrl by PreferenceLoader("") var coverPhoto by PreferenceLoader("") }
  180. • ·ͱΊ • %FMFHBUFEQSPQFSUJFTͷجຊ͸HFU7BMVFTFU7BMVFΦϖϨʔλ • ϓϩύςΟͷ৘ใ͸QSPQFSUZύϥϝʔλ͔ΒࢀরՄೳ • UIJT3FGύϥϝʔλ͸ϓϩύςΟ͕એݴ͞Ε͍ͯΔΫϥεͷ Πϯελϯε •

    ಛఆͷܕʹ੍ݶ͢Δ͜ͱ΋Մೳ • όΠϯυ࣌ʹॲཧ΍ϓϩύςΟͷݕࠪ౳Λ ͍ͨ͠ͱ͖͸QSPWJEF%FMFHBUF 1SFGFSFODF%FMFHBUFΛ࣮૷͢Δ
  181. -FUTDSFBUFZPVSEFMFHBUJPO

  182. 5JQT

  183. %FMFHBUFE1SPQFSUJFTͷ JOMJOF࠷దԽ

  184. • %FMFHBUFEQSPQFSUJFTΛར༻͢Δͱ ௨ৗͷϓϩύςΟΑΓ΋Φʔόʔϔου͕େ͖͍ %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ

  185. %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ class DelegateSample { var myProp: String by MyDelegate() }

  186. %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ class DelegateSample { private val myProp$delegate = MyDelegate() var

    myProp: String get() = myProp$delegate.getValue(this, this::myProp) set(value: String) = myProp$delegate.setValue(this, this::myProp, value) }
  187. %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ public final class DelegateSample { static final KProperty[] $$delegatedProperties

    = new KProperty[]{(KProperty)Reflection.mutableProperty1( new MutablePropertyReference1Impl( Reflection.getOrCreateKotlinClass(DelegateSample.class), "myProp", "getMyProp()Ljava/lang/String;"))}; @NotNull private final MyDelegate myProp$delegate = new MyDelegate(); @NotNull public final String getMyProp() { return this.myProp$delegate.getValue(this, $$delegatedProperties[0]); } public final void setMyProp(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.myProp$delegate.setValue(this, $$delegatedProperties[0], var1); } }
  188. %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ public final class DelegateSample { static final KProperty[] $$delegatedProperties

    = new KProperty[]{(KProperty)Reflection.mutableProperty1( new MutablePropertyReference1Impl( Reflection.getOrCreateKotlinClass(DelegateSample.class), "myProp", "getMyProp()Ljava/lang/String;"))}; @NotNull private final MyDelegate myProp$delegate = new MyDelegate(); @NotNull public final String getMyProp() { return this.myProp$delegate.getValue(this, $$delegatedProperties[0]); } public final void setMyProp(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.myProp$delegate.setValue(this, $$delegatedProperties[0], var1); } }
  189. %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ public final class DelegateSample { static final KProperty[] $$delegatedProperties

    = new KProperty[]{(KProperty)Reflection.mutableProperty1( new MutablePropertyReference1Impl( Reflection.getOrCreateKotlinClass(DelegateSample.class), "myProp", "getMyProp()Ljava/lang/String;"))}; @NotNull private final MyDelegate myProp$delegate = new MyDelegate(); @NotNull public final String getMyProp() { return this.myProp$delegate.getValue(this, $$delegatedProperties[0]); } public final void setMyProp(@NotNull String var1) { Intrinsics.checkParameterIsNotNull(var1, "<set-?>"); this.myProp$delegate.setValue(this, $$delegatedProperties[0], var1); } }
  190. • %FMFHBUFEQSPQFSUJFTΛར༻͢Δͱఆٛ͢Δͱ ௨ৗͷϓϩύςΟΑΓ΋Φʔόʔϔου͕େ͖͍ • QSPWJEF%FMFHBUFHFU7BMVFTFU7BMVFʹ౉͢ ϓϩύςΟͷϝλσʔλ ,1SPQFSUZ ͷ഑ྻΛੜ੒ • MB[ZͷΑ͏ʹ,1SPQFSUZ͕ඞཁͷͳ͍έʔε΋ଟ͘ɺ

    ഑ྻͷੜ੒͕ແବ %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ
  191. • 'SPN,PUMJO ༧ఆ  • ҎԼͷ৚݅Λຬͨ͢%FMFHBUFEQSPQFSUZ͸ ,1SPQFSUZ഑ྻʹϝλσʔλΛ֨ೲ͠ͳ͍ • QSPWJEF%FMFHBUFHFU7BMVFTFU7BMVFશ͕ͯJOMJOFؔ਺ •

    JOMJOFؔ਺Ͱ,1SPQFSUZΛࢀর͍ͯ͠ͳ͍ • શͯͷ%FMFHBUFEQSPQFSUZ্͕هΛຬͨ͢ͱ͖ ,1SPQFSUZ഑ྻࣗମΛੜ੒͠ͳ͍ %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ
  192. • ͜ͷػೳͷίϛοτϩάΛݟΔͱʜ %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ

  193. • ,1SPQFSUZOBNF͚ͩ͸ಛผʹࢀরՄೳͳΑ͏ʹ͢Δ ܭը͕͋Γͦ͏ͳงғؾ͕ͩʜ • ࠓͷॴ࣮૷͸͞Ε͍ͯͳͦ͞͏ %FMFHBUFEQSPQFSUJFTͷJOMJOF࠷దԽ

  194. طଘΫϥε΁ͷ%FMFHBUJPO

  195. • طଘΫϥεʹ%FMFHBUJPO͍ͨ͠ • طଘΫϥεͷ֦ுͱ͍͑͹֦ுؔ਺ طଘΫϥεʹ%FMFHBUJPO͢Δ

  196. طଘΫϥεʹ%FMFHBUJPO͢Δ operator fun String.getValue(thisRef: Any?, property: KProperty<*>) = this.length

  197. طଘΫϥεʹ%FMFHBUJPO͢Δ operator fun String.getValue(thisRef: Any?, property: KProperty<*>) = this.length class

    ExtensionDelegate { val length: Int by "delegate" fun main() { println(length) // 8 } }
  198. طଘΫϥεʹ%FMFHBUJPO͢Δ operator fun <T> SharedPreferences.getValue( thisRef: Any?, property: KProperty<*> ):

    T = this.all[property.name] as? T ?: throw IllegalArgumentException() operator fun <T> SharedPreferences.setValue( thisRef: Any?, property: KProperty<*>, value: T ) { val editor = edit() when (value) { is String -> editor.putString(property.name, value) is Boolean -> editor.putBoolean(property.name, value) // 省略 } editor.apply() }
  199. • ֦ுؔ਺ʹΑΔҕৡ • ඪ४ϥΠϒϥϦͰ͸ҙ֎ͱ࢖ΘΕ͍ͯΔ • 4UPSJOH1SPQFSUJFTJOB.BQ • -B[Z طଘΫϥεʹ%FMFHBUJPO͢Δ