当前位置: 首页 > 工具软件 > AsynTask > 使用案例 >

AsynTask

归浩博
2023-12-01

介绍:
AsyncTask是一种轻量级的异步任务类,可以在后台线程池中执行后台的任务,然后把执行的进度和最终的结果传递给主线程并在主线程中更新UI。从实现上来说,AsyncTask封装了Thread和Handler。但它并不适合特别耗时的任务,对于特别耗时的任务应该使用线程池。
它是一个泛型抽象类,Params表示参数的类型,Progress表示后台任务进度的类型,而Result表示结果的返回类。

使用特点:
(1)它必须在主线程中创建,execute方法必须在主线程中调用
(2)execute方法只能执行一次,虽然可以传很多个参数(任务)

工作原理:
AsyncTask实际上是对线程池和Handler进行了封装。
(1)任务执行:
3.0之前,AsyncTask是并行执行的,而3.0之后就变为了串行执行,并且开发者可以选择进行并行执行。原理是什么呢?实际上它内部有两个线程池,sDefaultExecutor是一个自己实现的串行的线程池,它是static的,说明一个进程内的所有任务都是它来执行,它的任务很简单,就是把任务放进一个队列中,然后提醒另一个并行的线程池THREAD_POOL_EXECUTOR来取出执行,如果有可取的并且当前没有任务在执行就会被这个并行的线程池来执行。如果有任务在执行自然不会执行,当这个任务执行完之后又会重新提醒并行的线程池THREAD_POOL_EXECUTOR来取出队列中的任务进行执行。所以从这个原理我们看出来它是串行执行的,原因就是老版本是串行的并且很多代码依赖于这个逻辑。
(2)任务结果分发
它的内部有一个static的handler,所以这也是它必须在UI线程中进行初始化的原因,这样可以保证Handler被正常的初始化。当任务执行完成后,就会将结果发送给Handler,使得其在主线程被执行。

sdk3.0前,使用内部的线程池,多线程并发执行。线程池大小等于5,最大达128
sdk3.0后,使用默认的serial线程池,执行完一个线程,再顺序执行下一个线程。sdk3.0<=current version <= sdk4.3时 线程池大小等于5,最大达128
sdk4.4后线程池大小等于 cpu count + 1,最大值为cpu count * 2 + 1
sdk3.0后有两种线程池的实现,默认为 Serial 线程池

public static final Executor SERIAL_EXECUTOR = new SerialExecutor();  
public static final Executor THREAD_POOL_EXECUTOR  
            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,  
                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);  
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;  
public static void setDefaultExecutor(Executor exec) {//设置默认线程池  
        sDefaultExecutor = exec;  
}  

SerialExecutor ,使用同步锁,一次执行一个线程

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);  
            }  
        }  
    }  

THREAD_POOL_EXECUTOR 并发线程池
asynctask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); //设置使用 并发线程池
//params 都是使用在doInBackground(Params… params);
asynctask.executeOnExecutor(executor, params); //可以自定义 线程池

可以通过上述两种办法使用并发线程池。

 类似资料:

相关阅读

相关文章

相关问答