AsyncTask(2)

使用AsyncTask的一个奇怪现象

项目上有一个查询本地联系人的操作是用AsyncTask来实现的,不断的点击,有时候就会请求挺长时间,通过调试发现doInBackground()未及时执行,肿么回事,难道AsyncTask不是异步的?

AsyncTask主要有二个部分:一个是与主线程的交互,另一个就是线程的管理调度。虽然可能多个AsyncTask的子类的实例,但是AsyncTask的内部Handler和ThreadPoolExecutor都是进程范围内共享的,其都是static的,也即属于类的,类的属性的作用范围是CLASSPATH,因为一个进程一个VM,所以是AsyncTask控制着进程范围内所有的子类实例。

内部会创建一个进程作用域的线程池来管理要运行的任务,也就就是说当你调用了AsyncTask#execute()后,AsyncTask会把任务交给线程池,由线程池来管理创建Thread和运行Therad。对于内部的线程池不同版本的Android的实现方式是不一样的:

3.0之前规定同一时刻能够运行的线程数为5个,线程池总大小为128。也就是说当我们启动了10个任务时,只有5个任务能够立刻执行,另外的5个任务则需要等待,当有一个任务执行完毕后,第6个任务才会启动,以此类推。而线程池中最大能存放的线程数是128个,当我们尝试去添加第129个任务时,程序就会崩溃。AsyncTask执行中最终触发的是把任务交给线池THREAD_POOL_EXECUTOR来执行,提交的任务并行的在线程池中运行,但这些规则在3.0之后发生了变化,3.0之后提交的任务是串行运行的,执行完一个任务才执行下一个,直接调用execute(params)触发的是sDefaultExecutor的execute(runnable)方法,而不是原来的THREAD_POOL_EXECUTOR

总结

1、默认的execute()是串行

task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, “”);

task.execute(“”);

这两个执行效果是一样的,都是串行执行

2、并行执行,默认是5个

task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"");

3、自己定义线程个数

/**
 * Creates a new {@code ThreadPoolExecutor} with the given initial
 * parameters and default rejected execution handler.
 *
 * @param corePoolSize the number of threads to keep in the pool, even
 *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
 * @param maximumPoolSize the maximum number of threads to allow in the
 *        pool
 * @param keepAliveTime when the number of threads is greater than
 *        the core, this is the maximum time that excess idle threads
 *        will wait for new tasks before terminating.
 * @param unit the time unit for the {@code keepAliveTime} argument
 * @param workQueue the queue to use for holding tasks before they are
 *        executed.  This queue will hold only the {@code Runnable}
 *        tasks submitted by the {@code execute} method.
 * @param threadFactory the factory to use when the executor
 *        creates a new thread
 * @throws IllegalArgumentException if one of the following holds:<br>
 *         {@code corePoolSize < 0}<br>
 *         {@code keepAliveTime < 0}<br>
 *         {@code maximumPoolSize <= 0}<br>
 *         {@code maximumPoolSize < corePoolSize}
 * @throws NullPointerException if {@code workQueue}
 *         or {@code threadFactory} is null
 */
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         threadFactory, defaultHandler);
}

Executor exec = new ThreadPoolExecutor(15, 200, 10,TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

task.executeOnExecutor(exec);



### Android AsyncTask 使用及其最佳实践 `AsyncTask` 是一种轻量级的异步任务类,用于在主线程之外执行后台操作并更新 UI 线程。它简化了线程管理的过程,但在现代开发中已被更先进的解决方案所取代。 #### 基本结构 `AsyncTask` 定义了一个简单的三阶段模型来处理耗时的操作: 1. **doInBackground**: 执行实际的后台计算工作[^1]。 2. **onPostExecute**: 将 `doInBackground` 的结果传递给此方法,在这里可以安全地更新 UI。 3. **onProgressUpdate**: 可选方法,允许发布进度更新到 UI 线程。 下面是一个典型的实现例子: ```java private class MyAsyncTask extends AsyncTask<Void, Integer, String> { @Override protected void onPreExecute() { super.onPreExecute(); // 初始化UI组件或其他准备工作 } @Override protected String doInBackground(Void... params) { int progress = 0; while (progress < 100) { try { Thread.sleep(200); // 模拟耗时操作 publishProgress(progress += 10); } catch (InterruptedException e) { e.printStackTrace(); } } return "Operation Completed"; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); // 更新UI上的进度条或者其他控件 } @Override protected void onPostExecute(String result) { super.onPostExecute(result); // 显示最终的结果或者关闭加载动画 } } ``` 尽管如此,当涉及到配置更改(如屏幕旋转)时,`AsyncTask` 存在一个主要缺陷——如果背景任务正在运行而发生了配置变化,则可能导致内存泄漏或崩溃[^2]。因此推荐使用 `AsyncTaskLoader` 或其他生命周期感知型架构组件替代传统方式。 另外值得注意的是,在某些情况下启动应用可能会因为初始化逻辑复杂而导致性能瓶颈;通过析工具比如 CPU Profiler 查看具体耗时较长的方法链路可以帮助定位问题所在位置[^3]。 最后考虑框架设计模式方面,无论是 MVC 还是 MVVM 都能有效离业务逻辑与视图展示层从而提高代码可维护性和扩展性[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值