【发布时间】:2020-06-20 14:06:39
【问题描述】:
我创建了以下应用程序来说明一些疑问。 My Example on the Github
在本例中,我将一个文件复制到另一个包中。
我的疑惑如下:
-
并行执行任务,是否可以返回取消前完成的值?
-
为什么在
contentResolver.openInputStream (uri)中出现消息“不适当的阻塞方法调用”,而我正在使用 IO 上下文? -
当我读取文件条目复制到输出时,我总是检查作业状态,以便当这个任务被取消时,它立即停止,创建的输出文件被删除并返回取消异常,是对吗?
-
我可以限定执行的任务数量吗?
我的 onCreate:
private val listUri = mutableListOf<Uri>()
private val job = Job()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//get files from 1 to 40
val packageName = "android.resource://${packageName}/raw/"
for (i in 1..40) {
listUri.add(Uri.parse("${packageName}file$i"))
}
}
我的按钮操作:
//Button action
fun onClickStartTask(view: View) {
var listNewPath = emptyList<String>()
CoroutineScope(Main + job).launch {
try {
//shows something in the UI - progressBar
withContext(IO) {
listNewPath = listUri.map { uri ->
async {
//path to file temp
val pathFileTemp =
"${getExternalFilesDir("Temp").toString()}/${uri.lastPathSegment}"
val file = File(pathFileTemp)
val inputStream = contentResolver.openInputStream(uri)
inputStream?.use { input ->
FileOutputStream(file).use { output ->
val buffer = ByteArray(1024)
var read: Int = input.read(buffer)
while (read != -1) {
if (isActive) {
output.write(buffer, 0, read)
read = input.read(buffer)
} else {
input.close()
output.close()
file.deleteRecursively()
throw CancellationException()
}
}
}
}
//If completed then it returns the new path.
return@async pathFileTemp
}
}.awaitAll()
}
} finally {
//shows list complete in the UI
}
}
}
我的取消作业按钮:
fun onClickCancelTask(view: View) {
if (job.isActive) {
job.cancelChildren()
println("Cancel children")
}
}
这将是执行任务的按钮操作。
感谢大家的帮助。
【问题讨论】:
-
I copy a file to another package?复制你一个包?那会是什么? -
@blackapps 复制位于一个位置并保存在另一个位置的文件。保留原始文件。
-
具体来自哪个位置?具体到哪个位置?
-
@blackapps 你可以更好地看到here,从原始文件夹到externalStorageDir。我只在问题中添加了我有这些疑问的代码部分。正如我所说,示例应用程序是为了说明我的疑问。
-
你说 externalStorageDir 但在你的代码中是 externalFilesDir。请给出确切的位置,不要以为我们会点击链接或查看示例应用程序。在这里做这一切。在此处发布可重现的代码。首先,raw 什么都没有。
标签: android kotlin asynchronous kotlin-coroutines fileinputstream