Android中的异步处理技术之AsyncTask

简介: 目录定义和作用AsyncTask是在Executor框架的基础上进行的封装,它实现将耗时任务移动到工作线程中进行,同时提供了方便的接口实现了工作线程和主线程的通信。

目录

img_6069bdc9da1377bdd610e80874cb37b4.png

定义和作用

AsyncTask是在Executor框架的基础上进行的封装,它实现将耗时任务移动到工作线程中进行,同时提供了方便的接口实现了工作线程和主线程的通信。

AsyncTask主要的方法

使用AsyncTask一般会用到如下方法

private static class MyTask extends AsyncTask<String,Integer,String>{
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected void onCancelled(String s) {
            super.onCancelled(s);
        }

        @Override
        protected String doInBackground(String... strings) {
            return null;
        }
}
onPreExecute() 系统自动调用,一般用于UI的初始化
onPostExecute(Params params) 系统自动调用,用于任务执行完毕后的操作
onProgressUpdate(Progress... progress) 系统自动调用,一般用于更新进度条
onCancelled(Result result) 系统自动调用,任务取消时调用此方法,同时onPostExecute方法将不会被调用了
doInBackground(Result... result) 系统自动调用,用于执行后台操作
excute(Params... params) 需要手动调用,调用后将开始任务
publishProgress(count) 需要手动调用,此方法在类的内部实现,一般用于更新进度条的数据

AsyncTask的使用方法

继承AsyncTask并实现其核心方法然后手动调用excute()方法。

public class MainActivity extends AppCompatActivity {
    private Button btStart;
    private ProgressBar pb;
    private TextView tvState;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btStart = (Button) findViewById(R.id.bt_start);
        pb = (ProgressBar) findViewById(R.id.pb);
        tvState = (TextView) findViewById(R.id.tv_state);
        final MyTask myTask=new MyTask(pb,tvState);
        btStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myTask.execute();
            }
        });
    }
    private static class MyTask extends AsyncTask<String,Integer,String>{
        @SuppressLint("StaticFieldLeak")
        private TextView textView;
        @SuppressLint("StaticFieldLeak")
        private ProgressBar progressBar;
        public MyTask(ProgressBar progressBar,TextView textView) {
            this.progressBar=progressBar;
            this.textView=textView;
        }

        @Override
        protected void onPreExecute() {
            textView.setText("开始加载");
        }

        @Override
        protected void onPostExecute(String s) {
            textView.setText("加载完毕");
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            progressBar.setProgress(values[0]);
        }

        @Override
        protected void onCancelled(String s) {
            textView.setText("已取消");
        }

        @Override
        protected String doInBackground(String... strings) {
            int count=0;
            try {
                while (count<=100){
                    count+=1;
                    Thread.sleep(50);
                    publishProgress(count);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "";
        }
    }
}

xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:text="开始"
        android:id="@+id/bt_start"
        android:layout_gravity="center"
        android:layout_height="wrap_content" />
    <ProgressBar
        android:layout_width="match_parent"
        android:layout_marginTop="20dp"
        android:max="100"
        android:id="@+id/pb"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_height="wrap_content" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_marginTop="20dp"
        android:text="状态"
        android:id="@+id/tv_state"
        android:layout_gravity="center"
        android:layout_height="wrap_content" />
</LinearLayout>
img_8bc1e31dc5a57e8b1342f43f0a6dbe26.gif

注意

  • AsyncTask必须在UI线程中启动
  • 同一个AsyncTask实例对象只能执行1次,若执行第2次将会抛出异常
  • AsyncTask最好声明为静态内部类
  • 在不同版本的Android系统的 AsyncTask的execute和executeOnExecutor方法的运行有些许差别


    img_dc5df5dd7a6cb7f2d96fabb1c3d6ca09.png

    可以看到,如果想要AsyncTask并行执行任务的话,那么在API大于13的版本中建议使用executeOnExecutor代替execute。另外如果 AsyncTask是异步执行,最多也只能有四个任务可以同时进行,其他任务需要在队列中排队,等待空闲线程。之所以会出现这种情况是由于AsyncTask的源码决定的。

public abstract class AsyncTask<Params, Progress, Result> {
    private static final String LOG_TAG = "AsyncTask";

    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    // We want at least 2 threads and at most 4 threads in the core pool,
    // preferring to have 1 less than the CPU count to avoid saturating
    // the CPU with background work
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE_SECONDS = 30;

    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };
    ...

个人技术博客:https://myml666.github.io/

目录
相关文章
|
1月前
|
Java 数据库 Android开发
Android异步之旅:探索AsyncTask
Android异步之旅:探索AsyncTask
23 0
|
3月前
|
存储 Java 开发工具
Android开发的技术与开发流程
Android开发的技术与开发流程
168 1
|
7月前
|
开发工具 Android开发
Android平台GB28181设备接入端语音广播技术探究和填坑指南
GB/T28181-2016官方规范和交互流程,我们不再赘述。
|
7月前
|
编解码 Android开发 数据安全/隐私保护
Android平台外部编码数据(H264/H265/AAC/PCMA/PCMU)实时预览播放技术实现
好多开发者可能疑惑,外部数据实时预览播放,到底有什么用? 是的,一般场景是用不到的,我们在开发这块前几年已经开发了非常稳定的RTMP、RTSP直播播放模块,不过也遇到这样的场景,部分设备输出编码后(视频:H.264/H.265,音频:AAC/PCMA/PCMU)的数据,比如无人机或部分智能硬件设备,回调出来的H.264/H.265数据,除了想转推到RTMP、轻量级RTSP服务或GB28181外,还需要本地预览甚至对数据做二次处理(视频分析、实时水印字符叠加等,然后二次编码),基于这样的场景诉求,我们开发了Android平台外部编码数据实时预览播放模块。
|
6月前
|
存储 传感器 定位技术
《移动互联网技术》 第四章 移动应用开发: Android Studio开发环境的使用方法:建立工程,编写源程序,编译链接,安装模拟器,通过模拟器运行和调试程序
《移动互联网技术》 第四章 移动应用开发: Android Studio开发环境的使用方法:建立工程,编写源程序,编译链接,安装模拟器,通过模拟器运行和调试程序
70 0
|
8天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
9 0
|
2月前
|
人工智能 vr&ar Android开发
探索安卓与iOS系统的技术进展
【2月更文挑战第4天】本文将探讨安卓与iOS两大操作系统在最新技术进展方面的差异与相似之处。我们将分析它们在人工智能、增强现实、隐私保护等方面的创新和发展,并展望未来可能出现的趋势。通过对比这两个操作系统的技术特点,读者将能够更好地了解并选择适合自己需求的智能设备。
|
7月前
|
开发工具 Android开发
Android平台GB28181设备接入端预置位查询(PresetQuery)探讨和技术实现
之前blog介绍了GB28181云台控制(PTZCmd)相关,本文主要是介绍下GB28181预置位查询。
|
3月前
|
安全 算法 JavaScript
安卓逆向 -- 关键代码定位与分析技术
安卓逆向 -- 关键代码定位与分析技术
42 0
|
3月前
|
SQL API Android开发
展望2022:Android 开发最新技术动向
展望2022:Android 开发最新技术动向
111 0
展望2022:Android 开发最新技术动向