Anko doAsyncResult协程

时间:2018-08-21 20:33:55

标签: android kotlin anko

我是anko和coroutines的新手,请问如果我问些琐碎的事情:)

所以我想做的是让用户单击一个按钮,然后我要从互联网下载JSON,将其存储在本地并进行解析。由于这两种操作都需要花费大量时间,因此我考虑使用anko协程。

第一个问题是:

1。我可以使用嵌套的doAsync调用,在第一个UIThread中调用第二个doAsync吗? 我尝试了一下,但似乎可行,但感觉不对,所以我想寻找一种更优雅的方式

示例:

doAsync {
            downloadFileFromUrl(fileUrl)

            uiThread {
                doAsync {
                    IOUtils.parseFile(context!!)
                    val database = AppDatabase.getInstance(context!!)
                    val results = database.resultsDao().all

                    uiThread {
                        //show Results
                    }
                }
            }
        }

2。在寻找解决方案来解决我的问题时,我发现了doAsyncResult。如果1不正确,这是正确的方法吗?我已经尝试使用它,但是使用布尔值时会出错。见下文:

    private fun downloadFileFromUrl(fileUrl: String): Boolean {

        try{
        //Download file. No doAsync calls here.
        //The procedure just returns true if successful or false in case of any errors

            return true
        } catch (e: Exception) {
            Log.e("Error: ", e.message)
            return false
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        parseButton.setOnClickListener {
            try {
                val downloadFileResult: (AnkoAsyncContext<Boolean>.() -> Boolean) = {
                    ::downloadFileFromUrl.invoke(fileUrl)
                }

                val downloadFileResultFutureValue: Future<Boolean> = doAsyncResult(null, downloadFileResult)

                //Continue processing if downloadFileResultFutureValue is true
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

此行

val downloadFileResultFutureValue: Future<Boolean> = doAsyncResult(null, downloadFileResult)

无法编译以下错误,但我不知道如何解决:

Type inference failed: Cannot infer type parameter T in 

fun <T, R> T.doAsyncResult
(
exceptionHandler: ((Throwable) → Unit)? = ...,
task: AnkoAsyncContext<T>.() → R
)
: Future<R>
None of the following substitutions

receiver: Boolean
arguments:
(
((Throwable) → Unit)?,
AnkoAsyncContext<Boolean>.() → Boolean
)

receiver: BlankFragment
arguments:
(
((Throwable) → Unit)?,
AnkoAsyncContext<BlankFragment>.() → Boolean
)
can be applied to

receiver: BlankFragment
arguments:
(
Nothing?,
AnkoAsyncContext<Boolean>.() → Boolean
)

预先感谢

1 个答案:

答案 0 :(得分:3)

这样做:

doAsync {
   // 1. Something
   uiThread {
      // 2. Nothing
      doAsync {

实际上并没有多大意义,除非(2)不是什么,而您只是省略了一些代码。
如果没有,则可以继续使用该版本:

doAsync {
   downloadFileFromUrl(fileUrl)
   IOUtils.parseFile(context!!)
   val database = AppDatabase.getInstance(context!!)
   val results = database.resultsDao().all

   uiThread {
      //show Results
   }
}

由于parseFile()始终依赖于downloadFileFromUrl(),并且一切都在协程中运行,因此通过反复添加来避免并发。