Slide 1

Slide 1 text

Intent.putExtras()←これ Yahoo! JAPAN 森洋之

Slide 2

Slide 2 text

in the Stone Age

Slide 3

Slide 3 text

val intent = Intent(this, MyActivity2::class.java) intent.putExtra("foo", "FOO") intent.putExtra("bar", 333) startActivity(intent)

Slide 4

Slide 4 text

val intent = Intent(this, MyActivity2::class.java) intent.putExtra("foo", "FOO") intent.putExtra("bar", 333) startActivity(intent) ・口伝でのみ伝えられる、必須パラメータ ・パラメータの型は、ムラハチレベルの掟

Slide 5

Slide 5 text

val intent = Intent(this, MyActivity2::class.java) intent.putExtra("foo", "FOO") intent.putExtra("bar", 333) startActivity(intent) ・キモい

Slide 6

Slide 6 text

val intent = Intent(this, MyActivity2::class.java) intent.putExtra("foo", "FOO") intent.putExtra("bar", 333) startActivity(intent) ・手続き的で、あまり読みたくないコード

Slide 7

Slide 7 text

拡張関数

Slide 8

Slide 8 text

inline fun Context.startActivity( noinline extras: (Intent.() -> Unit)? = null) { val intent = Intent(this, T::class.java) extras?.let { intent.extras() } startActivity(intent) }

Slide 9

Slide 9 text

startActivity{ putExtra("foo", "FOO") putExtra("bar", 333) } ・だいぶ読みやすくなった

Slide 10

Slide 10 text

startActivity{ putExtra("foo", "FOO") putExtra("bar", 333) } ・相変わらず、村の掟ベースのActivity起動

Slide 11

Slide 11 text

Companion Object

Slide 12

Slide 12 text

companion object { const val EXTRA_FOO = "foo" const val EXTRA_BAR = "bar" fun showFoo(context: Context, foo: String, bar: Int) { context.startActivity { putExtra(EXTRA_FOO, foo) putExtra(EXTRA_BAR, bar) } } }

Slide 13

Slide 13 text

MyActivity2.showFoo(this, "FOO", 333) ・型セーフ ・Null安全 ・村の掟からの解放

Slide 14

Slide 14 text

companion object { const val EXTRA_FOO = "foo" const val EXTRA_BAR = "bar" const val EXTRA_HOGE = "foo" const val EXTRA_FUGA = "bar" fun showFoo(context: Context, foo: String, bar: Int) { context.startActivity { putExtra(EXTRA_FOO, foo) putExtra(EXTRA_BAR, bar) } } fun showHoge(context: Context, hoge: String, fuga: String) { context.startActivity { putExtra(EXTRA_HOGE, hoge) putExtra(EXTRA_FUGA, fuga) } } } 受け付けるパターンが増えると

Slide 15

Slide 15 text

companion object { const val EXTRA_FOO = "foo" const val EXTRA_BAR = "bar" const val EXTRA_HOGE = "foo" const val EXTRA_FUGA = "bar" fun showFoo(context: Context, foo: String, bar: Int) { context.startActivity { putExtra(EXTRA_FOO, foo) putExtra(EXTRA_BAR, bar) } } fun showHoge(context: Context, hoge: String, fuga: String) { context.startActivity { putExtra(EXTRA_HOGE, hoge) putExtra(EXTRA_FUGA, fuga) } } }

Slide 16

Slide 16 text

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) when { intent.extras.containsKey(EXTRA_FOO) && intent.extras.containsKey(EXTRA_BAR) -> { // foo pattern } intent.extras.containsKey(EXTRA_HOGE) && intent.extras.containsKey(EXTRA_FUGA) -> { // hoge pattern } else -> throw IllegalArgumentException("staticメソッドから起動してね ") } }

Slide 17

Slide 17 text

Sealed Class

Slide 18

Slide 18 text

private sealed class Extras { data class Foo(val foo : String, val bar : Int) : Extras(), Parcelable { companion object { @JvmField @Suppress("unused") val CREATOR: Parcelable.Creator = object : Parcelable.Creator { override fun createFromParcel(source: Parcel): Foo = Foo(source) override fun newArray(size: Int): Array = arrayOfNulls(size) } } protected constructor(parcelIn: Parcel) : this(parcelIn.readString(), parcelIn.readInt()) override fun writeToParcel(dest: Parcel?, flags: Int) { dest?.writeString(foo) dest?.writeInt(bar) } override fun describeContents(): Int = 0 } data class Hoge(val hoge : String, val fuga : String) : Extras(), Parcelable { companion object { @JvmField @Suppress("unused") val CREATOR: Parcelable.Creator = object : Parcelable.Creator { override fun createFromParcel(source: Parcel): Hoge = Hoge(source) override fun newArray(size: Int): Array = arrayOfNulls(size) } } protected constructor(parcelIn: Parcel) : this(parcelIn.readString(), parcelIn.readString()) override fun writeToParcel(dest: Parcel?, flags: Int) { dest?.writeString(hoge) dest?.writeString(fuga) } override fun describeContents(): Int = 0 } }

Slide 19

Slide 19 text

private sealed class Extras { data class Foo(val foo : String, val bar : Int) : Extras(), Parcelable { companion object { @JvmField @Suppress("unused") val CREATOR: Parcelable.Creator = object : Parcelable.Creator { override fun createFromParcel(source: Parcel): Foo = Foo(source) override fun newArray(size: Int): Array = arrayOfNulls(size) } } protected constructor(parcelIn: Parcel) : this(parcelIn.readString(), parcelIn.readInt()) override fun writeToParcel(dest: Parcel?, flags: Int) { dest?.writeString(foo) dest?.writeInt(bar) } override fun describeContents(): Int = 0 } data class Hoge(val hoge : String, val fuga : String) : Extras(), Parcelable { companion object { @JvmField @Suppress("unused") val CREATOR: Parcelable.Creator = object : Parcelable.Creator { override fun createFromParcel(source: Parcel): Hoge = Hoge(source) override fun newArray(size: Int): Array = arrayOfNulls(size) } } protected constructor(parcelIn: Parcel) : this(parcelIn.readString(), parcelIn.readString()) override fun writeToParcel(dest: Parcel?, flags: Int) { dest?.writeString(hoge) dest?.writeString(fuga) } override fun describeContents(): Int = 0 } } 論外

Slide 20

Slide 20 text

Parcelize

Slide 21

Slide 21 text

private sealed class Extras { @Parcelize data class Foo(val foo : String, val bar : Int) : Extras(), Parcelable @Parcelize data class Hoge(val hoge : String, val fuga : String) : Extras(), Parcelable } ・Kotlin Android Extensionsで、Parcelableは簡単に作れる ・experimental注意

Slide 22

Slide 22 text

companion object { fun showFoo(context: Context, foo : String, bar : Int) { context.startActivity { putExtra(EXTRAS_KEY, Extras.Foo(foo, bar)) } } fun showHoge(context: Context, hoge : String, fuga : String) { context.startActivity { putExtra(EXTRAS_KEY, Extras.Hoge(hoge, fuga)) } } }

Slide 23

Slide 23 text

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) val extras = intent.getParcelableExtra(EXTRAS_KEY) ?: throw IllegalArgumentException("staticメソッドから起動してね ") when(extras) { is Extras.Foo -> { // foo pattern } is Extras.Hoge -> { // hoge pattern } } }

Slide 24

Slide 24 text

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) val extras = intent.getParcelableExtra(EXTRAS_KEY) ?: throw IllegalArgumentException("staticメソッドから起動してね ") when(extras) { is Extras.Foo -> { // foo pattern } is Extras.Hoge -> { // hoge pattern } } }

Slide 25

Slide 25 text

委譲Property

Slide 26

Slide 26 text

class ExtraParcelable : ReadOnlyProperty { override fun getValue(thisRef: Activity, property: KProperty<*>) : Parcelable { return thisRef.intent.getParcelableExtra(EXTRAS_KEY) ?: throw IllegalArgumentException("extra parameter ${property.name} is null") } }

Slide 27

Slide 27 text

private val extras by ExtraParcelable() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) when(extras) { is Extras.Foo -> { // foo pattern } is Extras.Hoge -> { // hoge pattern } } }

Slide 28

Slide 28 text

おまけ

Slide 29

Slide 29 text

改訂版が出ます ・2ヶ月半で500ページ書き直します