是使用lateinit的最佳方式?

有使用光标获取android所持有的图像的处理。光标需要授权到外部存储。 如果AndroidOS为6.0或更高,并且未获得授权许可,则应用程序将被终止。 如果获得许可,则关闭游标的处理是必要的。

如果是Java,那么写下如下的onStop会很好,除了Kotlin之外,会引发一个异常。

if (cursor != null ) cursor.close(); kotlin.UninitializedPropertyAccessException: lateinit property cursor has not been initialized 

所以我写了,我们初始化光标,并完成它。

 cursor = contentResolver.query( MediaStore.Images.Media.INTERNAL_CONTENT_URI, null, null, null, null ) 

这不会再引起异常,但似乎你写了不必要的代码,并没有更清楚。 但是,我不会迟到游标,我认为在声明的时候它是无用的代码。 另外,当声明private var cursor: Cursor? = Null private var cursor: Cursor? = Null ,我认为在各个地方都需要一个空的判断代码,我不认为它就像Kotlin一样。

如果你能给我如何写出最好的建议,我会很高兴。

这是使用的代码:

 private lateinit var cursor : Cursor private val PERMISSIONS_REQUEST_CODE = 100 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Android Version 6.0 later if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { initCursor() } else { requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), PERMISSIONS_REQUEST_CODE) } } else { // Android Version under 6.0 initCursor() } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { when (requestCode) { PERMISSIONS_REQUEST_CODE -> if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { initCursor() } else { finishApp() } else -> finishApp() } } private fun finishApp() { // It prevents kotlin.UninitializedPropertyAccessException of cursor(lateinit valiant). It's last resort... cursor = contentResolver.query( MediaStore.Images.Media.INTERNAL_CONTENT_URI, null, null, null, null) /* if(cursor != null) cursor.close() */ finish() } override fun onStop() { super.onStop() cursor.close() } private fun initCursor() { cursor = contentResolver.query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null) cursor.moveToFirst() } 

不,这不是最好的使用。 首先,使用lateinit是一个在使用时应该可用的变量。 使用可为空的变量可以是null,这对于lateinit是不同的,意思是它不应该是null。

这在Android中非常有用,因为您在onCreate初始化变量而不是构造函数。 依赖注入like Dagger也很好。

它抛出的UninitializedPropertyAccessException意味着你的Cursor在被访问的时候没有被初始化。 这意味着你的代码中有一个逻辑错误,即游标没有初始化就可以访问。

请注意,持有Cursor不是一个好的做法。 它拥有与数据库的连接。 使用后应该关闭并重新创建一个新的,而不是拿着它。