In this tutorial, we’ll be digging deep into AsyncTasks in android by discussing the different ways of executing it. We’ll see the different ways to handle configuration changes with Async Tasks too.
To know the basics of AsyncTasks, we recommend you to read this tutorial.

在本教程中,我们将通过讨论执行它的不同方法来深入研究android中的AsyncTasks。 我们还将看到使用异步任务处理配置更改的不同方法。
要了解AsyncTasks的基础知识,建议您阅读本教程。

Android AsyncTasks (Android AsyncTasks)

AsyncTasks is a helper class that lets us run background tasks which can communicate back with the UI thread.

AsyncTasks是一个帮助程序类,它使我们可以运行可以与UI线程通讯回来的后台任务。

Following are the main methods provided by the AsyncTask class:

以下是AsyncTask类提供的主要方法:

  • onPreExecuteonPreExecute
  • doInBackGrounddoInBackGround
  • onPostExecuteonPostExecute
  • onProgressUpdate – In order to invoke this, call the publishProgress method from the doInBackground method.onProgressUpdate –为了调用此方法,请从doInBackground方法中调用publishProgress方法。

The syntax to declare an AsyncTask is:

声明AsyncTask的语法是:

private static class MyAsyncTask extends AsyncTask<A, B, C>

Three types of arguments are passed :

传递了三种类型的参数:

  • A – These are the type of params that can be passed in the execute() method. They are used in the doInBackground.答–这些是可以在execute()方法中传递的参数类型。 它们在doInBackground中使用。
  • B – This type is available in the onProgressUpdateB –此类型在onProgressUpdate可用
  • C – This is the type present in the onPostExecute method.C –这是onPostExecute方法中存在的类型。

execute method is invoked on the instance to start the AsyncTask typically.

通常在实例上调用execute方法以启动AsyncTask。

AsyncTasks should be declared static. Otherwise, leaks would occur since non-static classes contain direct references to the Activities which can prevent the Activity from getting garbage collected if its closed while the AsyncTask is still running.
AsyncTasks应该声明为静态。 否则,会发生泄漏,因为非静态类包含对Activity的直接引用,如果AsyncTask仍在运行时关闭了该Activity,则可以防止该Activity被垃圾回收。

AsyncTasks并行执行 (AsyncTasks Parellel Execution)

Till Android Donut, Parallel Execution was not possible when multiple AsyncTasks were executed simultaneously.

到Android Donut为止,当同时执行多个AsyncTask时,并行执行是不可能的。

From Android Donut multiple async tasks were executed in parallel until Android Honeycomb 3.0 arrived.

从Android Donut并行执行多个异步任务,直到Android Honeycomb 3.0到来。

In order to do parallel Execution since Android 3.0, we need to call the method, executeOnExecutor(java.util.concurrent.Executor, Object[]) on the AsyncTask.

为了从Android 3.0开始执行并行执行,我们需要在AsyncTask上调用方法executeOnExecutor(java.util.concurrent.Executor, Object[])

Here a THREAD_POOL_EXECUTOR is passed for the Executor.

在这里,为执行器传递了THREAD_POOL_EXECUTOR

Note: AsyncTask is built using Java’s Executor Service

注意:AsyncTask是使用Java的Executor服务构建的

How many AsyncTasks are executed in parallel?并行执行多少个AsyncTask?

It depends on:
Core Pool Size (CORE_POOL_SIZE) (# of threads in the thread pool) = CPU Count + 1

这取决于:
核心池大小(CORE_POOL_SIZE)(线程池中的线程数)= CPU计数+ 1

Maximum Pool Size (MAXIMUM_POOL_SIZE) (max # of thread in the thread pool) = CPU Count * 2 +1

最大池大小(MAXIMUM_POOL_SIZE)(线程池中的最大线程数)= CPU计数* 2 +1

So for a smartphone with 4 core processor, 4*2 + 1 = 9 AsyncTasks can be run in parallel.

因此,对于具有4核心处理器的智能手机,可以并行运行4 * 2 + 1 = 9 AsyncTasks。

AsyncTasks内存泄漏和方向更改 (AsyncTasks Memory Leaks And Orientation Changes)

Whenever you define an AsyncTask in your code, the IDE does ask you to set the class as static inner class or memory leaks might occur. Why so?

每当您在代码中定义AsyncTask时,IDE都会要求您将类设置为静态内部类,否则可能会发生内存泄漏。 为什么这样?

Non-static inner classes hold a direct reference to the parent class. So if an AsyncTask lives longer than the Activity, it will prevent the Activity from getting garbage collected.

非静态内部类直接引用父类。 因此,如果AsyncTask的寿命长于Activity,则将阻止Activity收集垃圾。

Thus, we can define the AsyncTask as static or keep a WeakReference to the Activity in it.

因此,我们可以将AsyncTask定义为静态,或在其中保留对Activity的WeakReference。

A static object’s lifecycle is bound to the class it is contained in.
静态对象的生命周期绑定到其所包含的类。

An orientation change can cause IllegalStateException since the enclosed activities configuration changes while the AsyncTask is running in the background. This can lead to memory leaks.

方向更改可能会导致IllegalStateException,因为在AsyncTask在后台运行时,随附的活动配置会更改。 这可能导致内存泄漏。

So setting android:configChanges = “orientation” is one way to deal with AsyncTask and Screen rotation.
But this isn’t a good practice.

因此,设置android:configChanges =“ orientation”是处理AsyncTask和屏幕旋转的一种方法。
但这不是一个好习惯。

Another possible way is by locking the orientation to the current one in the onPreExecute and unlocking in the onPostExecute after the background work is over.

另一种可能的方法是,将方向锁定为onPreExecute中的当前方向,然后在后台工作结束后在onPostExecute中解锁。

The ideal way is to put an AsyncTask inside a Fragment and setRetainInstance(true).

理想的方法是将AsyncTask放入Fragment和setRetainInstance(true)

For the sake of simplicity and since we are focusing on Parallel Execution in this tutorial, we’ll set the configChanges in the AndroidManifest.xml file in our below project code.

为了简单起见,由于在本教程中我们将重点放在并行执行上,因此我们将在下面的项目代码中的AndroidManifest.xml文件中设置configChanges。

项目结构 (Project Structure)

码 (Code)

The code for the activity_main.xml layout is given below:

下面给出了activity_main.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="16dp"android:gravity="center"android:orientation="vertical"tools:context=".MainActivity"><ProgressBarandroid:id="@+id/progressBar1"style="?android:attr/progressBarStyleHorizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:max="10" /><ProgressBarandroid:id="@+id/progressBar2"style="?android:attr/progressBarStyleHorizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:max="10" /><Buttonandroid:id="@+id/btnSerialExecution"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="SERIAL EXECUTION" /><ProgressBarandroid:id="@+id/progressBar3"style="?android:attr/progressBarStyleHorizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:max="10" /><ProgressBarandroid:id="@+id/progressBar4"style="?android:attr/progressBarStyleHorizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:max="10" /><Buttonandroid:id="@+id/btnParallelExecution"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="PARELLEL EXECUTION" /></LinearLayout>

We’ve created 4 ProgressBar, 2 will be filled serially using AsyncTask progress updates and the remaining two would be executed parallelly. Let’s see the code for it.

我们已经创建了4个ProgressBar,其中2个将使用AsyncTask进度更新顺序填充,其余两个将并行执行。 让我们看看它的代码。

package com.journaldev.androidmultiasynctasks;import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;import java.lang.ref.WeakReference;public class MainActivity extends AppCompatActivity implements View.OnClickListener {Button btnParallelExecution, btnSerialExecution;ProgressBar progressBar1, progressBar2, progressBar3, progressBar4;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();}private void initViews() {btnSerialExecution = findViewById(R.id.btnSerialExecution);progressBar1 = findViewById(R.id.progressBar1);progressBar2 = findViewById(R.id.progressBar2);btnParallelExecution = findViewById(R.id.btnParallelExecution);progressBar3 = findViewById(R.id.progressBar3);progressBar4 = findViewById(R.id.progressBar4);btnSerialExecution.setOnClickListener(this);btnParallelExecution.setOnClickListener(this);}@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.btnSerialExecution:MyObject myObject = new MyObject(progressBar1, 2);MyAsyncTask aTask1 = new MyAsyncTask();aTask1.execute(myObject);myObject = new MyObject(progressBar2, 3);MyAsyncTask aTask2 = new MyAsyncTask();aTask2.execute(myObject);break;case R.id.btnParallelExecution:myObject = new MyObject(progressBar3, 2);MyAsyncTask aTask3 = new MyAsyncTask();aTask3.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, myObject);myObject = new MyObject(progressBar4, 3);MyAsyncTask aTask4 = new MyAsyncTask();aTask4.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, myObject);break;}}private static class MyAsyncTask extends AsyncTask<MyObject, Integer, Void> {private WeakReference<MyObject> myObjectWeakReference;@Overrideprotected Void doInBackground(MyObject... params) {this.myObjectWeakReference = new WeakReference<>(params[0]);for (int i = 0; i <= 10; i++) {publishProgress(i);try {Thread.sleep(myObjectWeakReference.get().interval * 100);} catch (InterruptedException e) {e.printStackTrace();}}return null;}@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);myObjectWeakReference.get().progressBar.setProgress(values[0]);}}private class MyObject {private ProgressBar progressBar;private int interval;MyObject(ProgressBar progressBar, int interval) {this.progressBar = progressBar;this.interval = interval;}}
}

We’ve created a Model class which is passed in the AsyncTask param.
It contains the ProgressBar instance and the interval for which the Thread would sleep.

我们创建了一个Model类,该类在AsyncTask参数中传递。
它包含ProgressBar实例以及线程将Hibernate的时间间隔。

The output of the above application in action is given below:

上面应用程序的输出如下:

This brings an end to this tutorial. You can download the project from the link below:

本教程到此结束。 您可以从下面的链接下载项目:

AndroidMultiAsyncTasksAndroidMultiAsyncTasks
Github Project LinkGithub项目链接

翻译自: https://www.journaldev.com/23605/android-asynctasks-parallel-execution

Android AsyncTasks并行执行相关推荐

  1. 我对Flutter的第一次失望

    老孟导读:此文翻译自:https://medium.com/@suragch/my-first-disappointment-with-flutter-5f6967ba78bf 我喜欢Flutter. ...

  2. flutter 阿里 号码认证_我对Flutter的第一次失望

    老孟导读:此文翻译自:https://medium.com/@suragch/my-first-disappointment-with-flutter-5f6967ba78bf 我喜欢Flutter. ...

  3. android AsyncTask 只能在线程池里单个运行的问题

    android 的AysncTask直接调用Execute会在在一个线程池里按调用的先后顺序依次执行. 如果应用的所有网络获取都依赖这个来做,当有一个网络请求柱塞,就导致其它请求也柱塞了. 在3.0 ...

  4. 对Android 开发者有益的 40 条优化建议(转)

    下面是开始Android编程的好方法: 找一些与你想做事情类似的代码 调整它,尝试让它做你像做的事情 经历问题 使用StackOverflow解决问题 对每个你像添加的特征重复上述过程.这种方法能够激 ...

  5. android java 多线程,Android多线程的四种方式

    当我们启动一个App的时候,Android系统会启动一个Linux Process,该Process包含一个Thread,称为UI Thread或Main Thread.通常一个应用的所有组件都运行在 ...

  6. android activity启动流程_1307页!一线大厂Android面试全套真题解析!

    /   前言   / 金九银十到了,很多读者都反映有面试的需求,所以我特地给大家准备了一点资料! 下面的题目都是大家在面试一线互联网大厂时经常遇到的面试真题和答案解析,如果大家还有其他好的题目或者好的 ...

  7. 【大厂攻略】Android开发3年当了2年咸鱼每天CRUD,复习2个月幸运拿下美团offer!

    前言 这是一个非常要好的朋友真实经历,觉得还挺励志的,希望能帮助到一些正在迷茫的同学. 是去美团送外卖了?有配电瓶车吗? 答:亲,有配的哦,开起来贼顺滑.啊呸,说啥了,咱进的是正儿八经的技术部门. 咸 ...

  8. 耗时118天爆肝【1296页】的“Android高级开发面试题”,终于成功上岸字节

    前言 本人16年毕业于一家普通二本,考研裂开了且没有实习经验,只做过两个项目,每天就是不断地投简历.刷面经,感觉自己都要抑郁了,最后勉强进入了一家学校合作的互联网公司,后面陆陆续续也换了几家公司,毕业 ...

  9. Android:面试官死亡问答,如何优化一个网络请求?大牛多个网络优化方案帮你解决!

    面试官:小萧啊,我好想你啊,你都好久没来找我面试了呀. 小萧:emmmmmmm,这不是怕被你打击吗. 面试官:ok,看来是有备而来,那么我们今天聊聊网络优化咋做吧. 小萧:我大意了,没有闪.老头子,你 ...

最新文章

  1. 通过 DLPack 构建跨框架深度学习编译器
  2. vue更新data无效,页面data没刷新 vue.set
  3. pytorch 获取模型参数_剑指TensorFlow,PyTorch Hub官方模型库一行代码复现主流模型...
  4. SQLServer 与 MySQL
  5. UVA11349 Symmetric Matrix【数学】
  6. 纯小白使用ffmpeg提取avi视频为MP3
  7. 7-3 算术入门之加减乘除 (10 分)
  8. 通配符星号(*)和问号(?)的区别
  9. RS485接口电路学习
  10. TimePicker使用全解
  11. 调试一个开源的车牌识别算法遇到的总结
  12. 计算机闹铃音乐是什么歌,适合当闹铃的歌曲
  13. html写小星星,写小星星的句子
  14. 树莓派Pico开发软件安装(Thonny)及烧录(flash)
  15. MeterSphere案例分享丨易盛信息MeterSphere接口测试使用经验
  16. 数据告诉你杜蕾斯是怎么风靡全球的?
  17. 服务器微信了早上好,微信早晨好问候语句动态图片 早上好发给朋友的微信早安问候语简短...
  18. 2021年南京大学软件工程电子信息专业考研指南
  19. 【亲测有效】解决执行nrm ls命令查看不到*星号的问题
  20. c语言单身狗题目罩得住学长,我家系统用爱发电

热门文章

  1. 【转】.Net 架构图
  2. UVALive 4212 Candy
  3. 2020-10-24 pandas导入出现错误或者警告解决方案
  4. [转载] python改写二分搜索算法_二分搜索算法模板python实现
  5. [转载] numpy总结
  6. VT-x is not available (VERR_VMX_NO_VMX).无法打开虚拟机,无法新建64位虚拟机
  7. java取得当前日期增加一天或多天
  8. JavaScript使用button提交表单
  9. 暑假集训 div1 B Derangement 交换数字 思维死角
  10. WCF 点滴启示录系列(一)