Android 在活动的init块中使用“this”作为上下文?
我正在用kotlin开发一个android应用程序 我有一个DerDatabaseHelper类,该类具有init块,该块使用通过类参数给定的上下文 DerDatabaseHelper是这样的Android 在活动的init块中使用“this”作为上下文?,android,kotlin,constructor,nullpointerexception,initialization,Android,Kotlin,Constructor,Nullpointerexception,Initialization,我正在用kotlin开发一个android应用程序 我有一个DerDatabaseHelper类,该类具有init块,该块使用通过类参数给定的上下文 DerDatabaseHelper是这样的 class DereDatabaseHelper(context: Context) { val manifestFile: File val fumensDBFile: File val fumenFolder: File val musicIDToInfo: Muta
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
class SongListActivity : AppCompatActivity() {
var dereDatabaseHelper : DereDatabaseHelper
init {
dereDatabaseHelper = DereDatabaseHelper(this)
}
我认为这段代码是正确的,但这段代码抛出了NullPointerException
java.lang.NullPointerException:尝试调用虚拟方法
'java.io.File android.content.Context.getExternalFilesDirjava.lang.String'
位于的空对象引用上
android.content.ContextWrapper.getExternalFilesDirContextWrapper.java:253
位于com.kyhsgeekcode.dereinfo.model.DereDatabaseHelper.DereDatabaseHelper.kt:21
位于com.kyhsgeekcode.dereinfo.SongListActivity.SongListActivity.kt:31
当执行在init块中时,此值是否为null?我应该使用什么初始化样式来修复此问题?构造函数或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)
当您启动任何活动时,您从未实例化活动类,为什么
因为这是安卓系统的责任,当您执行startActivityintent时,android系统使用默认构造函数实例化您的活动类,然后执行所有初始化,即提供上下文,一旦活动完全初始化,将调用活动的onCreate方法,您可以在其中执行初始化结束。切勿使用活动的构造函数活动来做任何涉及上下文的事情。Android通过反射使用其唯一的空构造函数实例化活动,然后在调用onCreate之前设置活动的各个字段。在活动中执行任何操作的第一个安全入口点是onCreate 您也不能调用活动的方法,因为它本身就是构造函数中的上下文 您甚至不能以任何方式使用上下文来设置属性,因为它们将在onCreate之前尝试访问上下文: 为了避免必须使属性为null,您可以执行以下任一操作,从而避免在调用onCreate之前实例化类:
class SongListActivity : AppCompatActivity() {
lateinit var dereDatabaseHelper : DereDatabaseHelper
override fun onCreate() {
super.onCreate
dereDatabaseHelper = DereDatabaseHelper(this)
}
或
你的意思是android不只是实例化我的活动类,然后调用onCreate,而是在实例化我的活动类时调用onCreate?谢谢你的更新答案和详细解释,谢谢!现在我明白了,在活动的构造函数和init块中执行任何操作都不是一个好主意。init和构造函数是否相同?。但现在我想知道为什么它会导致NullPointerException,因为这在java中无论如何都不应该为null,即使在构造函数中也是如此。您的意思是因为上下文尚未完全初始化,所以它为null吗?不,您传递给DerDatabaseHelper构造函数的this不是null。但在内部,Activity.getExternalFilesDir正在调用mBase.getExternalFilesDir,而mBase上下文的Java默认作用域实例仍然为null,因为尚未分配它。因此,NullPointerException不会发生在您自己的代码中。
class SongListActivity : AppCompatActivity() {
lateinit var dereDatabaseHelper : DereDatabaseHelper
override fun onCreate() {
super.onCreate
dereDatabaseHelper = DereDatabaseHelper(this)
}
class SongListActivity : AppCompatActivity() {
val dereDatabaseHelper by lazy { DereDatabaseHelper(this) }
}