首页 > 解决方案 > 如何在 doInBackgroung() 时制作 android AsyncTask 加载微调器

问题描述

我有一个用于 URL 连接的 AsyncTask。现在我希望每次进行 URL 连接时都有一个加载微调器。我在 中显示加载微调器onPreExecute()并在onPostExecute. 我whiledoInBackgroung(). 最大的问题是 GUI 冻结并且未显示加载微调器。在我看来,原因是URLconnection.execute().get()。但我需要 get() 因为活动需要结果才能使用它。

我现在的问题是:实现我的愿望的最佳方法是什么?(顺便说一句,使用“AsyncTask 解决方案”获得解决方案并不重要,因为可能有更好的解决方案,并且 AsyncTask 将在 SDK 版本 30 中被弃用)

非常感谢您并保持健康!

标签: javaandroidandroid-asynctask

解决方案


正如你所说的 AsyncTask 将被弃用。所以最好选择一个替代方案。

既然您提到您不依赖 AsyncTask,我将向您介绍另一种方法。

让我向您介绍协程,并说服您它们将解决您的问题并“完成工作”。

当我了解协程时,这个视频是第一个向我展示在我的应用程序中使用协程的潜力的示例之一。那时我还在使用 100% Java,可能就像你现在一样。

好的部分是:开始使用 Kotlin 真的很容易!您不仅可以从 Java 代码调用 Kotlin 函数,还可以从 Kotlin 代码调用 Java 函数。

要在 Kotlin 中“在后台做某事”,您需要做的就是launch一个协程(在后台线程上)。你有一个 ViewModel 来获取你的数据吗?如果可以选择将此文件传输到 kotlin,那么启动(和确定范围)协程就像this一样简单。对于片段或活动,您也可以使用其他应对方式。但是,通常不鼓励使用全局范围。

执行协程就这么简单:

class MyViewModel: ViewModel() {
    fun loadDataInBackgroundAndShowSpinner {
        viewModelScope.launch {
            // Coroutine that will be canceled when the ViewModel is cleared.

           // start your spinning

           // do all the heave data work on a background thread
           doInBackground()

          // end your spinning here
        }
    }

    suspend fun doInBackground(inputURL: String) {
        withContext(Dispatchers.IO) {
            // Execute all your data fetching here
            ...
            // Assign your data to your viewModel variables, post it to a LiveData object, etc.
        }
    }
}

您不需要主线程中的任何循环或任何东西。通过withContext在后台线程上使用,您可以实现main-safety。在启动的协程中,所有内容(默认情况下)都会按顺序执行。你仍然不会阻塞主线程。你是怎么做到的?这里的关键是你的doInBackground函数有suspend关键字。因此,您loadDataInBackgroundAndShowSpinner在主线程上将“暂停”您的doInBackground功能,并且主线程能够做任何您想做的事情(即没有冻结)。然后,一旦你doInBackground完成,它将恢复执行,你可以在主线程上再次关闭你的微调器。

Kotlin 协程让在后台做某事变得更加容易,我真的想鼓励你试一试!它肯定会解决您的问题,我想不出更简单的方法。Google 还试图让您从 Java 开始时尽可能容易。


推荐阅读