Android中的AsyncTask
来源:互联网 发布:后台数据集 js调用 编辑:程序博客网 时间:2024/06/06 01:25
AsyncTask有两种运行的方式,串行和并行。
以下是我做的一个测试例子有串行和并行,代码如下,可以看到两种方式的不同。
package com.example.xueqin.asynctaskdemo;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.support.annotation.Nullable;import android.view.View;import android.widget.Button;import android.widget.ProgressBar;/** * Created by xue.qin on 2017/6/12. */public class MainActivity extends Activity implements View.OnClickListener { Button button; ProgressBar progressBar1, progressBar2, progressBar3, progressBar4; Integer[] params = {0, 1, 2, 3}; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity_layout); progressBar1 = (ProgressBar) findViewById(R.id.progressbar1); progressBar2 = (ProgressBar) findViewById(R.id.progressbar2); progressBar3 = (ProgressBar) findViewById(R.id.progressbar3); progressBar4 = (ProgressBar) findViewById(R.id.progressbar4); button = (Button) findViewById(R.id.start); button.setOnClickListener(this); } @Override public void onClick(View v) { MyAsyncTask myAsyncTask1 = new MyAsyncTask(); MyAsyncTask myAsyncTask2 = new MyAsyncTask(); MyAsyncTask myAsyncTask3 = new MyAsyncTask(); MyAsyncTask myAsyncTask4 = new MyAsyncTask(); //并行调用 myAsyncTask1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0); myAsyncTask2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 1); myAsyncTask3.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 2); myAsyncTask4.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 3); //串行调用// myAsyncTask1.execute(0);// myAsyncTask2.execute(1);// myAsyncTask3.execute(2);// myAsyncTask4.execute(3); } class MyAsyncTask extends AsyncTask<Integer, Integer, String> { private int index = 0; @Override protected String doInBackground(Integer... params) { index = params[0]; int increase = 0; while (increase <= 100) { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } publishProgress(increase++); } return "complete"; } @Override protected void onProgressUpdate(Integer... values) { switch (index) { case 0: progressBar1.setProgress(values[0]); break; case 1: progressBar2.setProgress(values[0]); break; case 2: progressBar3.setProgress(values[0]); break; case 3: progressBar4.setProgress(values[0]); break; default: break; } } }}
并行调用:进度条是一起滚动的,如图
串行调用时依次进行的如图
源码分析。
1)第一种,串行调用,使用默认的线程池,来运行,调用下面的这个函数
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
接着调用这个executeOnExecutor()这里没有
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }
总之提交这个mFuture到线程池中执行,就会调用doInBackground()里的代码。
看一下这个sDefaultExecutor执行的代码:
private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } }
这里的逻辑应该是这样的,当第一次执行execute()时,mActive==null,执行scheduleNext(), 这里将Runnable提交到线程池运行,运行之后finnally继续调用scheduleNext()直到mTasks中没有runnable,所以是串行执行的。
这样的好处:
连续执行execute,只在第一次,开始scheduleNext(),之后自动调用,这中间,还是可以不断的向mTask中添加Runable,也就是说总会排队执行完所用的execute的runnable。
执行完成之后,下一次提交又是进入下一个循环。
scheduleNext为什么加锁:因为主线程和线程池都会调用到这个函数,不加锁,可能会重复调用,那么就有可能有并行的情况出现。ArrayDeque也不是线程安全的,会出现runnable重复执行等很多问题。同理execute也是因为ArrayDeque线程的不安全,可能会有在同一个index提交两个runnable,之前的就被顶掉了,等各种情况出现。
2)并行调用。
直接使用上面提到的executeOnExecutor这个函数,自定义线程池来调用。AsyncTask中已经写好了一个线程池,如下:
public static final Executor THREAD_POOL_EXECUTOR; static { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); threadPoolExecutor.allowCoreThreadTimeOut(true); THREAD_POOL_EXECUTOR = threadPoolExecutor; }
并使用静态块初始化了这个线程池。可以使用以下代码来使用这个线程池来调用,这个自然就是并行的了。
myAsyncTask1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0); myAsyncTask2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 1); myAsyncTask3.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 2); myAsyncTask4.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 3);
- Android中的AsyncTask
- Android中的AsyncTask
- 小结android中的AsyncTask
- 详解android中的AsyncTask
- Android中的AsyncTask
- Android中的AsyncTask
- Android中的AsyncTask
- android中的AsyncTask例子
- Android中的AsyncTask
- Android中的利器-AsyncTask
- android中的AsyncTask异步操作
- Android中的AsyncTask的使用
- android中的AsyncTask异步操作
- Android中的Handler和AsyncTask
- Android中的handler和AsyncTask
- Android中的多线程之AsyncTask
- Android中的AsyncTask异步类
- Android中的AsyncTask机制理解
- 你不知道的javascript之Object.create 和new区别
- Java简介
- 一个简单的爬虫程序,包含请求头。
- [Tomcat源码]-架构1
- Python使用struct模块转换C语言结构体,打包、解包二进制数据
- Android中的AsyncTask
- ARM处理器与51单片机程序编写的区别
- RecyclerView去掉滑动到边界阴影
- 65. Valid Number
- Caffe 模型微调 的场景、问题、技巧以及解决方案
- STM32中I2C协议时序和使用
- Linux下安装JDK1.7
- 在ubuntu中某目录下右键快速打开终端
- 软件设计模式整理