Сопрограммы Anko doAsyncResult

Я новичок в анко и сопрограммах, так что извините, если я прошу что-то тривиальное :)

Итак, я пытаюсь сделать так, чтобы пользователь нажал кнопку, а затем я хочу загрузить JSON из Интернета, сохранить его локально и проанализировать его. Поскольку обе операции могут занять значительное время, я решил использовать анко-сопрограммы.

Итак, первый вопрос:

1. Могу ли я использовать вложенные вызовы doAsync, вызывая второй doAsync в UIThread первого? Я попробовал, и, похоже, он работает, но мне кажется, что это неправильно, поэтому я пытался найти более элегантный способ.

Пример:

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
)

заранее спасибо

5
0
1 325
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Делая это:

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(), и все работает в сопрограмме, вы не станете более параллельным, добавив это взад и вперед.

Хорошо, если я правильно понял, что вы имеете в виду, все, что находится в doAsync, выполняется последовательно. Итак, сначала файл будет загружен. После загрузки файл будет проанализирован, и, наконец, будет вызвана база данных для отображения на экране. Что ж, теперь это имеет гораздо больше смысла :). Спасибо

Ioannis I 22.08.2018 21:48

Другие вопросы по теме