前人未踏の領域へ アプリ開発編

Android, iOSアプリ開発に関する調査メモ置き場。ほとんどAndroid。古い記事にはアプリ以外も含まれます。

Kotlin : 代入とgetterと by lazy

課題

こんなコードがあったとして

// 1 getter
val nickname: String?
    get() = _user.value?.nickname

// 2 代入
val nickname: String? = _user.value?.nickname

// 3 by lazy
val nickname: String? by lazy {
     _user.value?.nickname
}

// 4 関数
fun nickname(): String? = _user.value?.nickname

それぞれ何が違うのかがふと気になったので確認。

回答

  1. 都度処理結果が返される
  2. オブジェクト初期化時に一度だけ呼ばれ、以後変更されない
  3. 最初に参照された時点でブロックの処理結果が代入され、以後変更されない
  4. 都度処理結果が返される

4の記法が頭に残ってたせいで1を2に書き換えたくなったけど
冷静に考えたらそれってただの代入だから挙動違うよね、という話。

Android: BundleにEnumをセットする

課題

画面間の値渡しでBundleにEnumの値をセット、取得したい。どうすればよいか。

対応

EnumはSerializableなので Bundleの putSerializable メソッドが使える。

enum class Mark {
    HEART,
    SPADE,
    DIAMOND,
    CLUB
}


fun newInstance(): CardFragment {
    return CardFragment().apply {
        arguments = Bundle().apply {
            putSerializable("Mark", Mark.SPADE)
        }
    }
}
    override fun onAttach(context: Context) {
        super.onAttach(context)
        val mark:Mark = requireArguments().getSerializable("Mark")!! as Mark
    }

長いことAndroidやってるのに BundleにEnumそのままセットできるの知らんかった...。

Android: 追加のJava言語APIサポート(Java8)

Android Gradle Plugin を4.0.0以上にするとD8/R8のDesugaringによってほぼすべての端末でJava8の追加APIが利用できるようになりますよ、という記事。

medium.com

設定は以下の通り。coreLibraryDesugaringEnabledcoreLibraryDesugaring を追加すれば良いみたい。

android {
  defaultConfig {
    //Only required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

  compileOptions {
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
    // Sets Java compatibility to Java 8
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

dependencies {
  // Dependency with the implementation code for the APIs
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
}

これまではJava8の一部が使えるだけだったけど、さらに多くのJava8の機能が使えるようになったということかな。といっても本家はすでにJava14だけど。 java.time パッケージのクラスが使えるようになるのは朗報なので適用しておこう。