我现在遇到过几次崩溃,我已经看到了一些解决这个问题的方法,但首先我想让这次崩溃再次发生

I had this crash several times now, I have seen a few ways to solve this issue but first I would like to make this crash happen again

Fatal Exception: android.database.CursorIndexOutOfBoundsException
Index 0 requested, with a size of 0

这是我在 FileHelper 中的功能 class:

    fun downloadFile(url: String, fileName: String, completion: (DataResponse<File>) -> Unit) {

        val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager

        val uri = Uri.parse(url)

        val request = DownloadManager.Request(uri).apply {
            setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
                .setAllowedOverRoaming(false)
                .setTitle(fileName)
                .setDescription("")
                .setDestinationInExternalFilesDir(
                    context,
                    Environment.DIRECTORY_DOWNLOADS,
                    fileName
                )
        }

        val downloadId = downloadManager.enqueue(request)

        val query = DownloadManager.Query().setFilterById(downloadId)

        Thread {

            var downloading = true
            var downloadRepeatCount = 0
            while (downloading) {
                val cursor: Cursor = downloadManager.query(query)
                cursor.moveToFirst()

                val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
                if (status == DownloadManager.STATUS_SUCCESSFUL) {
                    val file =
                        File("${context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)}${fileName}")
                    downloading = false
                    completion(getSuccessResponseData(file))
                } else if (status == DownloadManager.STATUS_FAILED) {
                    downloading = false
                    sendFirebaseError("status STATUS_FAILED", url, fileName, uri)
                    completion(getErrorResponseData())
                } else {
                    if (downloadRepeatCount < 10 && status == DownloadManager.STATUS_PAUSED) {
                        Thread.sleep(1000)
                        downloadRepeatCount++
                    } else if (status == DownloadManager.PAUSED_QUEUED_FOR_WIFI) {
                        downloading = false
                        sendFirebaseError("status PAUSED_QUEUED_FOR_WIFI", url, fileName, uri)
                        completion(getErrorResponseData())
                    } else if (status == DownloadManager.ERROR_INSUFFICIENT_SPACE && status == DownloadManager.ERROR_DEVICE_NOT_FOUND) {
                        downloading = false
                        sendFirebaseError("status ERROR_INSUFFICIENT_SPACE and ERROR_DEVICE_NOT_FOUND", url, fileName, uri)
                        completion(getErrorResponseData())
                    } else if (status > 10) {
                        downloading = false
                        sendFirebaseError("status > 10", url, fileName, uri)
                        completion(getErrorResponseData())
                    } else {
                        downloading = true
                    }
                }
                cursor.close()
            }

        }.start()

    }

当我搜索此崩溃时,我收到了有关如何解决此问题的信息。但是,我想故意制造崩溃,以便确定它的原因。此外,我想知道如果可能的话,游标不会崩溃,但非致命错误会导致下载管理器进入 DownloadManager.STATUS_FAILED 状态。我想讨论这些话题。

您的查询没有匹配的行。您需要检查 cursor.moveToFirst() 的 return 值并仅在 return 为真时才调用 cursor.getInt()

确保你有空检查,正如@laalto 所说,只有当它为真时才调用该函数。

if( cursor != null && cursor.moveToFirst() ){
    status =cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
    cursor.close(); 
}

您可以使用此方法检查光标的大小:

if (cursor != null && cursor.getCount() > 0){
    // Do your stuff
}