在 activity 的初始化块中使用 'this' 作为上下文?
Using 'this' as Context in the init block of activity?
我正在使用 kotlin 开发 android 应用程序。
我有一个 DereDatabaseHelper
class,它有 init
块,它使用通过 class 参数给出的 context
(?)
DereDatabaseHelper
是这样的
class DereDatabaseHelper(context: Context) {
val manifestFile: File
val fumensDBFile: File
val fumenFolder: File
val musicIDToInfo: MutableMap<Int, MusicInfo> = HashMap()
val fumenIDToMusicID: SparseIntArray = SparseIntArray()
init {
val datadir = context.getExternalFilesDir(null).parentFile.parentFile
DereDatabaseHelper
class 在这里实例化 SongListActivity
是这样的。
class SongListActivity : AppCompatActivity() {
var dereDatabaseHelper : DereDatabaseHelper
init {
dereDatabaseHelper = DereDatabaseHelper(this)
}
我认为这段代码是正确的,但这段代码抛出 NullPointerException
。
java.lang.NullPointerException: Attempt to invoke virtual method
'java.io.File android.content.Context.getExternalFilesDir(java.lang.String)'
on a null object reference at
android.content.ContextWrapper.getExternalFilesDir(ContextWrapper.java:253)
at com.kyhsgeekcode.dereinfo.model.DereDatabaseHelper.<init>(DereDatabaseHelper.kt:21)
at com.kyhsgeekcode.dereinfo.SongListActivity.<init>(SongListActivity.kt:31)
在 init
块中执行时 this
是否为空,我应该使用什么初始化样式来解决这个问题?
活动未完全由 constructor
或您的 init
块初始化。
Android系统初始化活动,然后调用onCreate
方法。所以你应该做以下事情
override fun onCreate(savedInstanceState: Bundle?) {
// create instance of DareDatabaseHelper
}
为什么它不适用于构造函数?
考虑以下代码片段
var myActivity = MyActivity() // This doesn't start MainActivity
// This is how you start an activity
val intent = Intent(context, MyActivity::class.java)
startActivity(intent)
当你启动任何 activity 时,你永远不会实例化 activity class,为什么?
因为这是 android 系统的职责,当您执行 startActivity(intent)
android 系统会使用默认 [=12] 实例化您的 activity
class =] 然后进行所有初始化(即提供 context
)一旦 activity
完全初始化,您的 activity 的 onCreate
方法将被调用,您可以在其中执行您的操作初始化结束。
永远不要使用 Activity 的构造函数来做任何涉及上下文的事情。 Android 使用其唯一的空构造函数(通过反射)实例化 Activity,然后在 调用 之前设置 activity 的各个字段 onCreate()
.在 Activity 中执行任何操作的第一个安全入口点位于 onCreate()
.
您也不能在构造函数中调用 Activity(它本身就是一个上下文)的方法。
您也不能以任何方式使用上下文来设置属性,因为它们会在 onCreate
:
之前尝试访问上下文
class MyActivity: AppCompatActivity() {
val assets: AssetManager = getAssets() // This will cause a crash
}
为了避免必须使您的 属性 可为空,您可以执行以下任一操作,这样您就可以避免在调用 onCreate()
之前实例化您的 class:
class SongListActivity : AppCompatActivity() {
lateinit var dereDatabaseHelper : DereDatabaseHelper
override fun onCreate() {
super.onCreate
dereDatabaseHelper = DereDatabaseHelper(this)
}
或
class SongListActivity : AppCompatActivity() {
val dereDatabaseHelper by lazy { DereDatabaseHelper(this) }
}
我正在使用 kotlin 开发 android 应用程序。
我有一个 DereDatabaseHelper
class,它有 init
块,它使用通过 class 参数给出的 context
(?)
DereDatabaseHelper
是这样的
class DereDatabaseHelper(context: Context) {
val manifestFile: File
val fumensDBFile: File
val fumenFolder: File
val musicIDToInfo: MutableMap<Int, MusicInfo> = HashMap()
val fumenIDToMusicID: SparseIntArray = SparseIntArray()
init {
val datadir = context.getExternalFilesDir(null).parentFile.parentFile
DereDatabaseHelper
class 在这里实例化 SongListActivity
是这样的。
class SongListActivity : AppCompatActivity() {
var dereDatabaseHelper : DereDatabaseHelper
init {
dereDatabaseHelper = DereDatabaseHelper(this)
}
我认为这段代码是正确的,但这段代码抛出 NullPointerException
。
java.lang.NullPointerException: Attempt to invoke virtual method
'java.io.File android.content.Context.getExternalFilesDir(java.lang.String)'
on a null object reference at
android.content.ContextWrapper.getExternalFilesDir(ContextWrapper.java:253) at com.kyhsgeekcode.dereinfo.model.DereDatabaseHelper.<init>(DereDatabaseHelper.kt:21) at com.kyhsgeekcode.dereinfo.SongListActivity.<init>(SongListActivity.kt:31)
在 init
块中执行时 this
是否为空,我应该使用什么初始化样式来解决这个问题?
活动未完全由 constructor
或您的 init
块初始化。
Android系统初始化活动,然后调用onCreate
方法。所以你应该做以下事情
override fun onCreate(savedInstanceState: Bundle?) {
// create instance of DareDatabaseHelper
}
为什么它不适用于构造函数?
考虑以下代码片段
var myActivity = MyActivity() // This doesn't start MainActivity
// This is how you start an activity
val intent = Intent(context, MyActivity::class.java)
startActivity(intent)
当你启动任何 activity 时,你永远不会实例化 activity class,为什么?
因为这是 android 系统的职责,当您执行 startActivity(intent)
android 系统会使用默认 [=12] 实例化您的 activity
class =] 然后进行所有初始化(即提供 context
)一旦 activity
完全初始化,您的 activity 的 onCreate
方法将被调用,您可以在其中执行您的操作初始化结束。
永远不要使用 Activity 的构造函数来做任何涉及上下文的事情。 Android 使用其唯一的空构造函数(通过反射)实例化 Activity,然后在 调用 之前设置 activity 的各个字段 onCreate()
.在 Activity 中执行任何操作的第一个安全入口点位于 onCreate()
.
您也不能在构造函数中调用 Activity(它本身就是一个上下文)的方法。
您也不能以任何方式使用上下文来设置属性,因为它们会在 onCreate
:
class MyActivity: AppCompatActivity() {
val assets: AssetManager = getAssets() // This will cause a crash
}
为了避免必须使您的 属性 可为空,您可以执行以下任一操作,这样您就可以避免在调用 onCreate()
之前实例化您的 class:
class SongListActivity : AppCompatActivity() {
lateinit var dereDatabaseHelper : DereDatabaseHelper
override fun onCreate() {
super.onCreate
dereDatabaseHelper = DereDatabaseHelper(this)
}
或
class SongListActivity : AppCompatActivity() {
val dereDatabaseHelper by lazy { DereDatabaseHelper(this) }
}