Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/208.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在活动的init块中使用“this”作为上下文?_Android_Kotlin_Constructor_Nullpointerexception_Initialization - Fatal编程技术网

Android 在活动的init块中使用“this”作为上下文?

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

我正在用kotlin开发一个android应用程序

我有一个DerDatabaseHelper类,该类具有init块,该块使用通过类参数给定的上下文

DerDatabaseHelper是这样的

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) }
}