目的

Androidのcontextについてのメモ

初心者なりに調べてみました。

環境について

  • Android Studio 3.5.2
  • kotlin 1.3.50

参照サイト

Android Developers Context
Qiita ContextのおさらいとApplicationContextをどこからでも参照できるようにする方法
Qiita Androidのライフサイクルからアプリ設計を見直してみる

どれもとても参考になる記事なのですが、掲載時期が古いので情報事態も古い可能性があります。

contextとは

文脈、前後関係という意味。
Android上での役割は上記サイトより

Android Developersより
Interface to global information about an application environment.
This is an abstract class whose implementation is provided by the Android system.
It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

アプリ情報を持つインターフェース。アプリのリソースやクラスを呼び出すことができるもの。
という解釈です。

AdapterとかAlertDialogとかを利用するときに使うことが多く、個人的に重要なobjectだと思ってます。

で、このcontextが非常にやっかいな存在だと思っています。

contextのやっかいさ

参照サイトでも記載ありますが、contextは2種類あり、

  • ActivityやServiceが持っているcontext
  • Applicationが持っているcontext があります。
    それで詳しくは書きませんが、両者の使い方を誤るとメモリリークや、UIがおかしくなったりするそうです。

私的感覚ですが、
Adapterの場合は、どちらを使っても良いみたいですが、
AlertDialogの場合はActivityが持っているcontextを使わないとクラッシュするようです。

それで、
Activityで使うならば別に大した問題じゃないのですが、問題はFragmentです。

FragmentでDialogを使う場合は、どのようにActivityのcontextを取得しようかということです。

context取得方法

以下にcontextを取得する方法を記載します。
自分が調査した結果3つ方法ありまして、先の2つがActivityが持つcontextを渡す方法です。

ただ、正直落とし穴がある気がします。
こんな簡単な方法で済むのであれば、正直ここまで燃り上がらないと思います。

直接contextを渡す

Activityでの渡し方は以下。

Activityからの渡し方
val transaction = supportFragmentManager.beginTransaction()
transaction.add(R.id.menu_fragment, Fragment.createInstance(this))
transaction.addToBackStack(null)
transaction.commit()

Fragmentでの受け取り方法は以下

Fragmentでの受け取り方法
private var mContext: Context? = null

...

companion object {
    fun createInstance(context: Context): Fragment {
        val fragment = Fragment()
        fragment.mContext = context
        return fragment
    }
}

Acctivityのcontextをコマンドで取得する

activityコマンドだけで取得できる。

activity
AlertDialog.Builder(activity?)...

Applicationが持っているcontextをコマンドで取得する

activity.applicationContextコマンドで取得できる。

activity.applicationContext
Adapter(activity.applicationContext, data)

懸念点

上で書いたことに関して懸念点があります。
まず、
わざわざ、直接contextを渡す 必要がない点。activityコマンドで取得できるんだから

でも、直接渡す方法も幾らかのサイトで紹介されています。
ということはactivityコマンドだとnullになったりすることがあるのでしょうか。
activityのライフサイクルで停止してしまった時など。。

そこまでは調査できていません。

また、参考サイトに記載ありますが、わざわざApplicationContextをstatic化 していて。
ここまでする必要あるのかと思ったりもする。こちらもactivity.applicationContextコマンドで取得できない場面がある!?

という不安があり、まだまだ勉強不足です。

まぁ、そもそもAlertDialogを使わないという手もあると思いました。
Dialog関連のメソッドが結構deprecatedになっているようですし。

初心者なりに調べてみました。(逃げ)

以上です。