美文网首页Android适配经验Android过时方法处理程序员
【Android】使用更好的解决方案替代 AsyncTask

【Android】使用更好的解决方案替代 AsyncTask

作者: Tyhoo_Wu | 来源:发表于2020-11-03 22:30 被阅读0次

    前言:AsyncTask 负责在 Android 中执行异步任务,它允许我们以非线程阻塞的方式执行操作。但是在 API 30,AsyncTask 被 Android 标记为 Deprecated。

    官方文档:
    https://developer.android.google.cn/reference/android/os/AsyncTask

    官方给出的解决方案是:
    Use the standard java.util.concurrent or Kotlin concurrency utilities instead.


    一、什么是 AsyncTask?

    在Java中,AsyncTask 实现如下所示:

    class SampleAsyncTask extends AsyncTask<Void, Void, Void> {
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
    
        @Override
        protected Void doInBackground(Void... voids) {
            return null;
        }
    
        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }
    
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
        }
    }
    

    执行AsyncTaskexecute,首先触发onPreExecute回调,然后交给线程池sDefaultExecutor调度,mFuture配合mWorker开启子线程,触发doInBackground回调,然后交给内部单例InternalHandler处理返回结果并返回到主线程,最后根据Message处理onProgressUpdateonPostExecute

    关于 AsyncTask 源码解析可以看我写的另一篇文章:
    【Android】深入解析 AsyncTask 源码


    二、为什么 AsyncTask 在 Android 中被废弃?

    在 Android 中的AsyncTask有太多问题,例如:由于AsyncTaskActivityFragment的生命周期无关而导致的内存泄漏等等。

    如果你对执行AsyncTask使用不当,最终会在意想不到的地方发生崩溃。这对于用户和开发人员来说都不是好事。

    官方文档给出我们两种替代方案:

    • Java 代码:ExecutorThreadPoolExecutorFutureTask
    • Kotlin 代码:Kotlin 协程

    三、针对 Java 代码,使用 Executors 替代

    Executors 是一种结构化的服务,可以管理多个线程(池)。 可以指定要在内存中保留多少个线程。 如果提供的线程池数量超出可接受的数量,它们将被保留在队列中。

    注:确保仅创建一个ExecutorService实例。

    示例代码:

    public class TestActivity extends AppCompatActivity {
    
        private ExecutorService executorService;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            executorService = Executors.newFixedThreadPool(1);
            doAsyncCode();
        }
    
        private void doAsyncCode() {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    // 执行你的耗时操作代码
                    ...
                    
                    doOnUiCode();
                }
            });
        }
    
        private void doOnUiCode() {
            Handler uiThread = new Handler(Looper.getMainLooper());
            uiThread.post(new Runnable() {
                @Override
                public void run() {
                    // 更新你的UI
                }
            });
        }
    
        @Override
        protected void onStop() {
            super.onStop();
    
            if (!executorService.isShutdown()) {
                executorService.shutdownNow();
            }
        }
    }
    

    四、针对 Kotlin 代码,使用 Kotlin coroutines 替代

    导入协程库:

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
    

    示例代码:

    class MainActivity : AppCompatActivity() {
        val errorHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
            // 发生异常时的捕获
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
    
            GlobalScope.launch(errorHandler) {
                withContext(Dispatchers.IO) {
                    // 执行你的耗时操作代码
                    ...
    
                    doOnUiCode()
                }
            }
        }
    
        private suspend fun doOnUiCode() {
            withContext(Dispatchers.Main) {
                // 更新你的UI
            }
        }
    }
    

    © 2020 Tyhoo Wu, All rights reserved.

    相关文章

      网友评论

        本文标题:【Android】使用更好的解决方案替代 AsyncTask

        本文链接:https://www.haomeiwen.com/subject/ocgivktx.html