Android Kotlin基礎講座 01.3: イメージリソースと互換性

Android Kotlin基礎講座01.3 Android Kotlin基礎講座

タスク:ビューを効率よく見つける

ここまででアプリは問題なく動作します。しかし現在のただ機能するだけのコードにはまだ改良の余地があります。アプリ開発者は効率的なコードの書き方、快適な動作をするアプリについて理解する必要があります。アプリは高価な端末上でなくとも、またネットワーク接続が最適な状態でなくても、なるべく良い動作をするように設計されているべきです。また、アプリにさらに機能を追加していったときにもスムーズに動作し続けなければなりませんし、コードも整っていて読みやすいものであったほうが良いです。

このタスクではアプリをより効率的なものにする方法を学習していきます。

  1. まだ開いていなければMainActivityを開いてください。rollDice()メソッドの中のdiceImage変数の宣言部分を見てください。
val diceImage : ImageView = findViewById(R.id.dice_image)

rollDice()はRollボタンのクリックハンドラーであるため、ユーザーがこのボタンをタップする度にアプリはfindViewById()メソッドを呼び出し、ImageViewに対する参照を取得します。Androidシステムが毎回ビューヒエラルキー全体を検索するのは大きな負担がかかるので、findViewById()を呼び出す回数は最小限に留めるべきです。

このような小さなアプリであればそれほど大きな問題ではありません。もしより複雑なアプリを動作の重い端末で作動させる場合、findViewById()を何度も呼び出すとアプリがラグを起こすことがあります。
今回はその代わりにfindViewById()を一度だけ呼び出して、フィールドにビューオブジェクトを保存します。フィールドにイメージビューの参照を保存しておくことで、システムがそのビューに対していつでも直接アクセスできるようになるので、パフォーマンスの向上につながります。

  1. クラスの一番上のonCreate()の前に、イメージビューを保存するためのフィールドを作成してください。
    At the top of the class, before onCreate(), create a field to hold the ImageView.
var diceImage : ImageView? = null

理想的には変数は宣言された時かコンストラクターによって出来上がったときに同時に初期化されるのが良いのですが、Androidアクティビティはコンストラクターを持っていません。実際にはレイアウト上のビューはonCreate()メソッドの中のsetContentView()メソッドによってインフレートされるまでは、メモリー上ではアクセスできるオブジェクトとして扱われません。ですのでそれらの処理が終わるまではdiceImage変数は初期化できないのです。

そこで選択肢としてあるのが、今回の例のようにdiceImageをnullを許可する変数として定義することです。変数が宣言された時点ではnullにし、onCreate()の中でfindViewById()を用いて実際のイメージビューを代入します。しかしながら、これだとdiceImage変数を使おうとする度に毎回nullかどうかをチェックする必要があるので、コードが複雑になります。そこでより良い方法があります。

  1. nullの指定を削除して、lateinitというキーワードを使ってdiceImageを宣言します。
lateinit var diceImage : ImageView

lateinitキーワードはKotlinコンパイラーに変数がコードによって初期化される前から、この変数が必ず初期化されることを約束する意味で使われます。したがって、ここでnullとして初期化する必要はなくなり、変数を使うときにも絶対にnullでない変数として扱うことができます。フィールドがビューを持っているこのような場合にはlateinitを使うのが最適です。

  1. onCreate()の中のsetContentView()メソッドのあとにイメージビューの参照を取得するためにfindViewById()を使ってください。
diceImage = findViewById(R.id.dice_image)
  1. rollDice()の中のイメージビューを取得するために宣言した古いコードは削除してください。フィールドにdiceImageを宣言しているのでもう必要ありません。
val diceImage : ImageView = findViewById(R.id.dice_image)
  1. 予期した通りに動くかもう一度アプリを起動してみてください。

コメント

プロフィール

プロフィール
コードラボJP

大学卒業後SEに就職、現在は退職しフリーランスとして活動中。
『初心者でも挫折せずに一人でプログラミングを学べる』をモットーに、コードラボJPを開設
お問い合わせ等はcodelabsjp@gmail.comまで

コードラボJPをフォローする
タイトルとURLをコピーしました