I got a NullPointerException which appeared strange at first (or rather still does). The corresponding code is:
class Player(
    private val scope: CoroutineScope,
    private val ctx: Context
) {
    init {
        Log.d("FOO", ctx.toString())
        Log.d("FOO", ctx.cacheDir.toString())
    }
    ...
}
class MainActivity : AppCompatActivity() {
    val player = Player(lifecycleScope, this)
    ...
}
The log output is:
FOO/de.andrekr.android.box.MainActivity@90d5f8e
AndroidRuntime/Shutting down VM
AndroidRuntime/FATAL EXCEPTION: main
               Process: de.andrekr.android.box, PID: 30690
               java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{de.andrekr.android.box/de.andrekr.android.box.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getCacheDir()' on a null object reference
Note how it prints de.andrekr.android.box.MainActivity@90d5f8e, proving that ctx is not null but then when I call getCacheDir() I get the NPE.
I found this answer that says:
But an Activity isn't a context exactly, it has access to one
So how does this work in Java terms? Activity extends Context, doesn't it? How can ctx change from being Activity to being null? Especially since it's immutable (Kotlin val)?
