由于主线程负责处理用户输入事件, 如果主线程被阻塞,应用就会报ANR错误.为了不阻塞主线程,我们需要在子线程中处理耗时的操作,在处理耗时操作的过程中,子线程可能需要更新UI控件的显示, 由于UI控件的更新重绘是由主线程负责的,所以子线程需要通过Handler发送消息到主线程的消息对列中, 由运行在主线程的消息处理代码接收到消息后更新UI控件的显示.
采用线程+Handler实现异步处理时,当每次执行耗时操作都创建一条新线程进行处理,性能开销会比较大, 如果耗时操作执行的时间比较长,就有可能同时运行着许多线程,系统终将不堪重负. 为了提高性能我们使用AsyncTask实现异步处理,事实上其内部也是采用线程+handler来实现异步处理的.只不过是其内部使用了JDK5提供的线程池技术,有效的降低了线程创建数量及限定了同时运行的线程数,还有一些针对性的对池的优化操作.
AsyncTask内部使用了JDK5后的线程池ThreadPoolExecutor,在内部自定义配置了AsyncTask的专用线程池sExecutor执行者。而这种线程池的配置需要对系统和业务的理解来定的.我们一般默认最好,而JDK也建议我们使用它提供的几个已经封装好的类.
还是先看一看关于AsyncTask的代码
[html] view plaincopy
public abstract class AsyncTask<Params, Progress, Result> {
private static final String LOG_TAG = "AsyncTask";
//核心线程数5;
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;//最大线程数128
// 当线程数大于核心时,终止当前多余的空闲线程等待新任务的最长时间10(单位未知)
private static final int KEEP_ALIVE = 10;
//创建10容量的基于已链接节点的、范围任意的 blocking queue。此队列按 FIFO(先进先出)排序元素
private static final BlockingQueue<Runnable> sWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
//定制内部线程池的生成线程的简单工厂,并为每个任务指定 了一个递增的唯一的id
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());
}
};
/**
* 创建线程池(看配置好像是文档中所说的小队列较大池policy)
*/
private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
private static final int MESSAGE_POST_RESULT = 0x1;
private static final int MESSAGE_POST_PROGRESS = 0x2;
private static final int MESSAGE_POST_CANCEL = 0x3;
//又在内部准备了一个处理器(由于这个AsyncTask在UI线程中使用,所以这个InternalHandler是主线程的啦)
private static final InternalHandler sHandler = new InternalHandler();
//工作任务封装类
private final WorkerRunnable<Params, Result> mWorker;
private final FutureTask<Result> mFuture;
//volatile类型的枚举值, 默认表示为PENDING未执行状态
private volatile Status mStatus = Status.PENDING;
/**
* Indicates the current status of the task. Each status will be set only once
* during the lifetime of a task.
*/
public enum Status {
/**
* Indicates that the task has not been executed yet.
*/
PENDING,
/**
* Indicates that the task is running.
*/
RUNNING,
/**
* Indicates that {@link AsyncTask#onPostExecute} has finished.
*/
FINISHED,
}
//构造方法
[html] view plaincopy
/**
* Creates a new asynchronous task
* This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
//设置任务执行的优先级比默认线程优先级略低一些
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return doInBackground(mParams); //回调doInBackGround(数组)方法
}
};
//用mWorker创建一个可取消的异步计算任务
mFuture = new FutureTask<Result>(mWorker) {
//当任务不管是正常终止、异常或取消而完成的,都回调此方法, 即isDone()为true时
@Override
protected void done() {
Message message;
Result result = null;
try {
result = get();
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
//当发生CancellationException异常时说明任务被取消了, 消息通知UI线程
message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
message.sendToTarget();
return;
} catch (Throwable t) {
throw new RuntimeException("An error occured while executing "
+ "doInBackground()", t);
}
//正常结束任务后发消息执行MESSAGE_POST_RESULT的回调操作
message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
}
};
}
[html] view plaincopy
public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
ExecutionException, TimeoutException {
return mFuture.get(timeout, unit);
}
//这是AsyncTask异步任务的启动方法
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
//首先判断AsyncTask异步任务的状态,当处于RUNNING和FINISHED时就报IllegalStateException非法状态异常
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;
sExecutor.execute(mFuture);
return this;
}
[html] view plaincopy
protected final void publishProgress(Progress... values) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
private void finish(Result result) {
if (isCancelled()) result = null;
onPostExecute(result);
mStatus = Status.FINISHED;
}
//这个就是它的内部回调机制的回调方法处理
private static class InternalHandler extends Handler {
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
case MESSAGE_POST_CANCEL:
result.mTask.onCancelled();
break;
}
}
}
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
//对结果的封装
@SuppressWarnings({"RawUseOfParameterizedType"})
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
好了这就是AsyncTask的全部代码,里面省略了部分回调和基本的获取任务信息的代码,而这此也都是对JDK5并发库中类的封装使用,有兴趣的可以看看,这里不做过多解释.
首先来理一下AsyncTask的执行过程.
1, 首先我们一般先在主线程中创建一个AsyncTask类的匿名内部类, 并指明它的三个范型的参数化类型.
而在其构造方法中做了一件事,准备了一个将要执行的可取消的任务赋值给mFuture,
首先实现了WorkerRunnable 抽象类mWorker,并在其call执行方法中回调在后台执行的doInBackground()方法并params预设给这个方法.
然后用这个mWorker准备创建new FutureTask<Result>(mWorker)并在其done()方法中用result =get();等待执行的结果,当这个后台执行的FutureTask被取消后并捕获到CancellationException异常就用InternalHandler类型的sHandler向主线程发送标志为MESSAGE_POST_CANCEL|结果为Null的消息.而任务被正常执行完成后向主线程发送MESSAGE_POST_RESULT|结果为result的消息.
2, 在匿名内部类中我们重写四个onPostExecute, onPreExecute, onProgressUpdate, onCancelled
在主线程执行的方法, 和 一个doInBackground实际后台工作的方法
3, 当我们做完这一切后,调用execute(params)首先设置状态sStataus为Status.RUNNING,执行onPreExecute();回调,然后将params赋值给WorkerRunnable的params数组最后将构造中准备好的mFuture交给线程池中执行.
4. 剩下的事就是在done中等待执行结果.然后向主线程发送消息.而处理器已经准备了三种消息类别分别对应了不同的响应:
1) MESSAGE_POST_RESULT: onPostExecute(result);
2) MESSAGE_POST_PROGRESS: onProgressUpdate(result.mData);
3) MESSAGE_POST_CANCEL: onCancelled()
还有一个问题我注意到MESSAGE_POST_PROGRESS我看到是在publishProgress方法中发送的.
protected final void publishProgress(Progress... values) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
newAsyncTaskResult<Progress>(this, values)).sendToTarget();
}
而在AsyncTask类内部并没有对这个publishProgress方法的调用而这个方法又是protected的,通过查看文档这个方法的最佳调用时机是在doInBackground方法中向UI主线程publish updates,
另外也必须强调的是AsyncTask这个抽象类内部只用一个protected abstract Result doInBackground(Params... params);的抽象方法,在实现这个类的时候是必须要准备好这个后台执行的方法,其他可选.
写到这也差不多了,
再向大家介绍我对AsyncTask类的简单封装使用方法(当在应用中多处使用同样的异步任务时可以考虑)
首先把这个异步任务类独立出来,并类的构造中指定自定义的接口实现
[html] view plaincopy
public class MyAsyncTask extends AsyncTask <Params, Progress, Result>{
private ResponseInterface response;
public MyAsyncTask (ResponseInterface response) {
this.response = response;
}
/**
* 对asyncTask任务的简单封装的接口,
* 在使用此任务时主线程的工作就放在这个接口方法中实现
* 后台任务交给该任务的doInBackground
*/
public interface ResponseInterface{
void preRunning();
void finished(Result result);
}
/**
* 任务执行前
*/
@Override
protected void onPreExecute() {
response. preRunning ();
super.onPreExecute();
}
/**
* 任务执行后
*/
@Override
protected void onPostExecute(Result result) {
if(null != result){
response. finished (result);
}
super.onPostExecute(result);
}
@Override
protected Boolean doInBackground(Params... params) {
//doSomething();
return true;
}
/**
* 任务执行进度更新
*/
@Override
protected void onProgressUpdate(Progress... values) {
super.onProgressUpdate(values);
}
/**
* 任务完取消后执行
*/
@Override
protected void onCancelled() {
super.onCancelled();
}
}
这样的话后台执行的业务逻辑与前台UI的执行就分离出来的,在使用时只要new出这个AsyncTask异步任务类并指定这个内部接口的实现类就可以了,在前台只做前台的事,后台则交给这个自定义的AsyncTask异步任务类来实现.
采用线程+Handler实现异步处理时,当每次执行耗时操作都创建一条新线程进行处理,性能开销会比较大, 如果耗时操作执行的时间比较长,就有可能同时运行着许多线程,系统终将不堪重负. 为了提高性能我们使用AsyncTask实现异步处理,事实上其内部也是采用线程+handler来实现异步处理的.只不过是其内部使用了JDK5提供的线程池技术,有效的降低了线程创建数量及限定了同时运行的线程数,还有一些针对性的对池的优化操作.
AsyncTask内部使用了JDK5后的线程池ThreadPoolExecutor,在内部自定义配置了AsyncTask的专用线程池sExecutor执行者。而这种线程池的配置需要对系统和业务的理解来定的.我们一般默认最好,而JDK也建议我们使用它提供的几个已经封装好的类.
还是先看一看关于AsyncTask的代码
[html] view plaincopy
public abstract class AsyncTask<Params, Progress, Result> {
private static final String LOG_TAG = "AsyncTask";
//核心线程数5;
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;//最大线程数128
// 当线程数大于核心时,终止当前多余的空闲线程等待新任务的最长时间10(单位未知)
private static final int KEEP_ALIVE = 10;
//创建10容量的基于已链接节点的、范围任意的 blocking queue。此队列按 FIFO(先进先出)排序元素
private static final BlockingQueue<Runnable> sWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
//定制内部线程池的生成线程的简单工厂,并为每个任务指定 了一个递增的唯一的id
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());
}
};
/**
* 创建线程池(看配置好像是文档中所说的小队列较大池policy)
*/
private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
private static final int MESSAGE_POST_RESULT = 0x1;
private static final int MESSAGE_POST_PROGRESS = 0x2;
private static final int MESSAGE_POST_CANCEL = 0x3;
//又在内部准备了一个处理器(由于这个AsyncTask在UI线程中使用,所以这个InternalHandler是主线程的啦)
private static final InternalHandler sHandler = new InternalHandler();
//工作任务封装类
private final WorkerRunnable<Params, Result> mWorker;
private final FutureTask<Result> mFuture;
//volatile类型的枚举值, 默认表示为PENDING未执行状态
private volatile Status mStatus = Status.PENDING;
/**
* Indicates the current status of the task. Each status will be set only once
* during the lifetime of a task.
*/
public enum Status {
/**
* Indicates that the task has not been executed yet.
*/
PENDING,
/**
* Indicates that the task is running.
*/
RUNNING,
/**
* Indicates that {@link AsyncTask#onPostExecute} has finished.
*/
FINISHED,
}
//构造方法
[html] view plaincopy
/**
* Creates a new asynchronous task
* This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
//设置任务执行的优先级比默认线程优先级略低一些
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return doInBackground(mParams); //回调doInBackGround(数组)方法
}
};
//用mWorker创建一个可取消的异步计算任务
mFuture = new FutureTask<Result>(mWorker) {
//当任务不管是正常终止、异常或取消而完成的,都回调此方法, 即isDone()为true时
@Override
protected void done() {
Message message;
Result result = null;
try {
result = get();
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
//当发生CancellationException异常时说明任务被取消了, 消息通知UI线程
message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
message.sendToTarget();
return;
} catch (Throwable t) {
throw new RuntimeException("An error occured while executing "
+ "doInBackground()", t);
}
//正常结束任务后发消息执行MESSAGE_POST_RESULT的回调操作
message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
}
};
}
[html] view plaincopy
public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
ExecutionException, TimeoutException {
return mFuture.get(timeout, unit);
}
//这是AsyncTask异步任务的启动方法
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
//首先判断AsyncTask异步任务的状态,当处于RUNNING和FINISHED时就报IllegalStateException非法状态异常
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;
sExecutor.execute(mFuture);
return this;
}
[html] view plaincopy
protected final void publishProgress(Progress... values) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
private void finish(Result result) {
if (isCancelled()) result = null;
onPostExecute(result);
mStatus = Status.FINISHED;
}
//这个就是它的内部回调机制的回调方法处理
private static class InternalHandler extends Handler {
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
case MESSAGE_POST_CANCEL:
result.mTask.onCancelled();
break;
}
}
}
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
//对结果的封装
@SuppressWarnings({"RawUseOfParameterizedType"})
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
好了这就是AsyncTask的全部代码,里面省略了部分回调和基本的获取任务信息的代码,而这此也都是对JDK5并发库中类的封装使用,有兴趣的可以看看,这里不做过多解释.
首先来理一下AsyncTask的执行过程.
1, 首先我们一般先在主线程中创建一个AsyncTask类的匿名内部类, 并指明它的三个范型的参数化类型.
而在其构造方法中做了一件事,准备了一个将要执行的可取消的任务赋值给mFuture,
首先实现了WorkerRunnable 抽象类mWorker,并在其call执行方法中回调在后台执行的doInBackground()方法并params预设给这个方法.
然后用这个mWorker准备创建new FutureTask<Result>(mWorker)并在其done()方法中用result =get();等待执行的结果,当这个后台执行的FutureTask被取消后并捕获到CancellationException异常就用InternalHandler类型的sHandler向主线程发送标志为MESSAGE_POST_CANCEL|结果为Null的消息.而任务被正常执行完成后向主线程发送MESSAGE_POST_RESULT|结果为result的消息.
2, 在匿名内部类中我们重写四个onPostExecute, onPreExecute, onProgressUpdate, onCancelled
在主线程执行的方法, 和 一个doInBackground实际后台工作的方法
3, 当我们做完这一切后,调用execute(params)首先设置状态sStataus为Status.RUNNING,执行onPreExecute();回调,然后将params赋值给WorkerRunnable的params数组最后将构造中准备好的mFuture交给线程池中执行.
4. 剩下的事就是在done中等待执行结果.然后向主线程发送消息.而处理器已经准备了三种消息类别分别对应了不同的响应:
1) MESSAGE_POST_RESULT: onPostExecute(result);
2) MESSAGE_POST_PROGRESS: onProgressUpdate(result.mData);
3) MESSAGE_POST_CANCEL: onCancelled()
还有一个问题我注意到MESSAGE_POST_PROGRESS我看到是在publishProgress方法中发送的.
protected final void publishProgress(Progress... values) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
newAsyncTaskResult<Progress>(this, values)).sendToTarget();
}
而在AsyncTask类内部并没有对这个publishProgress方法的调用而这个方法又是protected的,通过查看文档这个方法的最佳调用时机是在doInBackground方法中向UI主线程publish updates,
另外也必须强调的是AsyncTask这个抽象类内部只用一个protected abstract Result doInBackground(Params... params);的抽象方法,在实现这个类的时候是必须要准备好这个后台执行的方法,其他可选.
写到这也差不多了,
再向大家介绍我对AsyncTask类的简单封装使用方法(当在应用中多处使用同样的异步任务时可以考虑)
首先把这个异步任务类独立出来,并类的构造中指定自定义的接口实现
[html] view plaincopy
public class MyAsyncTask extends AsyncTask <Params, Progress, Result>{
private ResponseInterface response;
public MyAsyncTask (ResponseInterface response) {
this.response = response;
}
/**
* 对asyncTask任务的简单封装的接口,
* 在使用此任务时主线程的工作就放在这个接口方法中实现
* 后台任务交给该任务的doInBackground
*/
public interface ResponseInterface{
void preRunning();
void finished(Result result);
}
/**
* 任务执行前
*/
@Override
protected void onPreExecute() {
response. preRunning ();
super.onPreExecute();
}
/**
* 任务执行后
*/
@Override
protected void onPostExecute(Result result) {
if(null != result){
response. finished (result);
}
super.onPostExecute(result);
}
@Override
protected Boolean doInBackground(Params... params) {
//doSomething();
return true;
}
/**
* 任务执行进度更新
*/
@Override
protected void onProgressUpdate(Progress... values) {
super.onProgressUpdate(values);
}
/**
* 任务完取消后执行
*/
@Override
protected void onCancelled() {
super.onCancelled();
}
}
这样的话后台执行的业务逻辑与前台UI的执行就分离出来的,在使用时只要new出这个AsyncTask异步任务类并指定这个内部接口的实现类就可以了,在前台只做前台的事,后台则交给这个自定义的AsyncTask异步任务类来实现.
发表评论
-
android 应用内存分析
2013-03-11 17:53 2740Dalvik虚拟机支持垃圾收 ... -
NDK开发环境搭建_r8(转贴)
2012-12-21 15:03 951NDK开发环境搭建_r8 本文主内容: 1、 ... -
JSON数据的上传与解析过程
2012-10-31 17:56 11847Anroid上数据的交互有很多,XML,JSON,SOCKET ... -
android json解析及简单例子
2012-10-31 17:55 721JSON的定义: ... -
Android Service那些不得不说的事-之二(Bound Service的实现方式)
2012-10-31 10:28 7257To provide binding for service, ... -
Android Service那些不得不说的事-之一
2012-10-31 10:28 4154必须谨记的几点: 1. service的所有onXXXX( ... -
Android多线程任务优化:实现后台预读线程
2012-10-11 10:20 4135Android多线程任务优化:实现后台预读线程 分类: And ...
相关推荐
- **生命周期**:AsyncTask 的生命周期与 Activity 关联,如果 Activity 被销毁,那么与之相关的 AsyncTask 也可能会被取消。 - **内存泄漏**:由于 AsyncTask 与创建它的上下文有关,如果不正确地处理,可能会导致...
最新AsyncTask源码
在实际的开发中过程,我们可能经常要求应用程序做一些“耗时操作”,例如网络下载,加载大量资源等。这时候我们就不能直接在UI线程中(主线程)中去完成这些“耗时操作”,因为,UI线程主要是用来更新界面UI,如果一次...
Android的AsyncTask是一个轻量级的异步任务框架,它被设计用来简化在主线程与后台线程之间进行数据交互的复杂性。由于Android的UI更新必须在主线程中进行,AsyncTask通过内部封装Handler和线程池,使得开发者可以在...
AsyncTask源码(版本:Android4.3,含注释)
1. **生命周期管理**:AsyncTask与Activity的生命周期紧密关联。如果在Activity中创建的AsyncTask在其销毁前没有完成,可能会引发内存泄漏。因此,通常建议在Activity的onPause()或onDestroy()中取消正在运行的...
但是,需要注意的是,由于Android系统对AsyncTask的限制,当Activity销毁后,与之关联的AsyncTask可能仍然在后台运行,这可能导致内存泄漏或意外的结果。因此,开发者需要在Activity的生命周期方法中适当地取消或...
本文将深入探讨 AsyncTask 的内部实现原理、工作流程以及关键代码分析。 首先,AsyncTask 有三个泛型参数,分别代表输入参数类型(Params)、进度更新参数类型(Progress)和结果参数类型(Result)。通过这些参数...
本篇文章将深入探讨AsyncTask的源码,并通过与反编译后的代码进行对比,揭示其内部工作机制。 首先,AsyncTask是一个抽象类,它提供了三个泛型参数:Params、Progress和Result。Params代表执行任务时需要的输入参数...
`Handler`通常与`Looper`配合使用,创建一个消息循环,使得`Handler`能够接收到并处理来自其他线程的消息。`Handler`的工作原理是,当创建一个`Handler`对象时,它会与当前线程的`Looper`关联,然后可以发送`Message...
`AsyncTask`还提供了取消任务、监控任务进度等功能,但需要注意的是,由于`AsyncTask`的生命周期与Activity绑定,若Activity被销毁,未完成的`AsyncTask`可能会导致内存泄漏。 接下来是`ListView`的优化。`ListView...
总结来说,正确理解和使用`AsyncTask`的`cancel()`方法对于优化Android应用的性能和用户体验至关重要。开发者需要确保在`doInBackground()`中正确处理`InterruptedException`,并在`onCancelled()`和`onPostExecute...
Handler 常用来多线程之间传递消息,AsyncTask 内部实现 InternalHandler,用来发送和处理消息 MESSAGE_POST_RESULT、MESSAGE_POST_PROGRESS,对应 AsyncTask 的回调方法 onProgressUpdate 和 onPostExecute,这两个...
下面我们将深入探讨AsyncTask的使用、原理以及如何更新UI。 首先,AsyncTask有三个泛型参数:`Param`, `Progress`, 和 `Result`。它们分别代表异步任务的输入参数类型、任务执行过程中的进度更新类型以及任务完成后...
- 由于Android系统的内存管理机制,Activity销毁后,与之关联的AsyncTask可能会被系统回收,导致异常。因此,若Activity可能被销毁,应在`onDestroy()`中取消AsyncTask的执行。 - Android 3.0及以上版本,...
总结,Android录音功能结合`AsyncTask`异步任务,可以实现用户友好的音频录制与上传服务。通过`MediaRecorder`进行录音,然后使用自定义的`AsyncTask`将录制的音频文件上传到服务器,确保了操作的非阻塞性和用户体验...
在Android开发中,`Handler`、`AsyncTask`和`Looper`是三个关键组件,用于在后台线程和主线(UI)线程之间进行通信,处理异步任务和更新用户界面。下面将详细阐述这三个组件的工作原理以及如何使用它们。 **Handler...
Android是单线程模型,耗时的操作必须放在非主线程中执行,对此,我们需要使用多线程/线程池或者AsyncTask等来完成异步加载任务。 博客地址:http://blog.csdn.net/chenzheng8975/article/details/53893666
5. **注意AsyncTask的生命周期**:AsyncTask与创建它的Activity有绑定关系,如果Activity被销毁,AsyncTask可能会导致内存泄漏。因此,确保在Activity的`onDestroy()`方法中取消并移除对AsyncTask的所有引用。 ```...