我现在遇到过几次崩溃,我已经看到了一些解决这个问题的方法,但首先我想让这次崩溃再次发生
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
}
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
}