我的Android进阶之旅------>Android中AsyncTask源码分析

时间:2021-10-21 23:48:17

我的Android进阶之旅------>Android中AsyncTask源码分析

在我的《我的Android进阶之旅------>android异步加载图片显示,并且对图片进行缓存实例》文章中,先后使用了Handler和AsyncTask两种方式实现异步任务机制。

下面先来看一段代码,这段代码是用来显示条目时候调用的方法。

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = null;
TextView textView = null; if (convertView == null) {
convertView = layoutInflater.inflate(listviewItem, null);
imageView = (ImageView) convertView.findViewById(R.id.imageView);
textView = (TextView) convertView.findViewById(R.id.textView);
convertView.setTag(new DataWrapper(imageView, textView));//将内容包装起来以备以后使用
} else {
DataWrapper dataWrapper=(DataWrapper) convertView.getTag();//将包装类取出来
//从包装类中取数据
imageView=dataWrapper.getImageView();
textView=dataWrapper.getTextView();
}
Contact contact=data.get(position);
textView.setText(contact.getName());
/**异步加载图片文件*/
asynchImageLoad(imageView,contact.getImage());
return convertView;
}

一开始asychImageLoad方法是使用Handler+Thread来实现的,代码如下所示:

private void asynchImageLoad(final ImageView imageView, final String imagePath) {
final Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {//运行在主线程中
Uri uri=(Uri) msg.obj;
if (uri!=null&&imageView!=null) {
imageView.setImageURI(uri);
}
}
};
Runnable runnable=new Runnable() {
@Override
public void run() {
try {
Uri uri=ContactService.getImage(imagePath, cache);
handler.sendMessage(handler.obtainMessage(10,uri));
} catch (Exception e) {
e.printStackTrace();
}
}
};
new Thread(runnable).start();
}

由于使用Handler实现的时候,因为每次显示一个条目的时候都会新建一个线程,因此如果直接从第一个条目拉到第一千个条目的时候,就会新建一千个线程,性能开销太大。

因此我采用了AsyncTask来代替Handler+Thread方式来实现异步任务机制,其实AsyncTask是对Handler+Thread进行了良好的封装,并且加入了线程池技术,有效的降低了线程创建数量及限定了同时运行的线程数。实现代码如下所示:

 /**异步加载图片文件*/
private void asynchImageLoad(ImageView imageView, String imagePath) {
AsycImageTask asycImageTask=new AsycImageTask(imageView);
asycImageTask.execute(imagePath);
}
/**
* 使用AsyncTask提高性能
* 可选方法:
1, onprogressupdate(progress…) 可以使用进度条增加用户体验度。此方法在主线程执行,用户显示任务执行的进度。
2, onpreExecute() 这里是最新用户调用excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
3, onCancelled() 用户调用取消时,要做的操作。 AsyncTask<Params, Progress, Result>
AsyscTask定义了三种泛型类型params,progress和result.
1, params启动任务执行的输入参数,比如http请求的URL
2, progress后台任务执行的百分比
3, result后台执行任务最终返回的结果,比如String,比如我需要得到的list。 使用AsyncTask类,遵守的准则:1, Task的实例必须在UI thread中创建;2, Execute方法必须在UI thread中调用
3, 不要手动的调用onPfreexecute(),onPostExecute(result)Doinbackground(params…),onProgressupdate(progress…)这几个方法;
4, 该task只能被执行一次,否则多次调用时将会出现异常;
AsyncTask的整个调用过程都是从execute方法开始的,一旦在主线程中调用execute方法,就可以通过onpreExecute方法,
这是一个预处理方法,比如可以在这里开始一个进度框,同样也可以通过onprogressupdate方法给用户一个进度条的显示,增加用户体验;
最后通过onpostexecute方法,相当于handler处理UI的方式,在这里可以使用在doinbackground得到的结果处理操作UI。
此方法在主线程执行,任务执行的结果作为此方法的参数返回
*/
private final class AsycImageTask extends AsyncTask<String, Integer, Uri>{
private ImageView imageView;
public AsycImageTask(ImageView imageView) {
this.imageView=imageView;
}
/**
* 后台执行,比较耗时的操作都可以放在这里。
注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作
,通常需要较长的时间。在执行过程中可以调用
publishProgress(Progress... values)来更新任务的进度。
*/
@Override
protected Uri doInBackground(String... params) {//子线程中执行
try {
return ContactService.getImage(params[0], cache);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 相当于handler处理UI的方式,在这里可以使用在doinbackground得到的结果
* 处理操作UI。此方法在主线程执行,任务执行的结果作为此方法的参数返回。
*/
@Override
protected void onPostExecute(Uri result) {//运行在主线程
if (result!=null&&imageView!=null) {
imageView.setImageURI(result);
}
} }

==============================下面我们来分析AsyncTask源码=====================================

1、我们来看一下AsyncTask的大纲视图

我的Android进阶之旅------>Android中AsyncTask源码分析

查看一下AsyncTask的定义,如下所示:

  public abstract class AsyncTask<Params, Progress, Result> 

其中 Params指定了doInBackground()方法的输入参数类型,代表”启动任务执行的输入参数“

Progress指定了onProgressUpdate()方法输入参数类型,代表“后台任务执行的进度”

Result指定了onPostExecute()方法输入参数的类型和doInBackground()方法返回值的类型,代表“后台计算结果的类型”

在特定场合下,并不是所有类型都被使用,如果没有被使用,可以用java.lang.Void类型代替。

2、查看AsyncTask任务执行的方法 exectute方法,因为执行一个异步任务都需要在代码中调用此方法,触发异步任务的执行。

public final AsyncTask<Params, Progress, Result> execute(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;
sExecutor.execute(mFuture); return this;
}

通过以上代码可以发现,首先执行的是onPreExecute()方法,该方法在UI线程中运行,可以在该方法中做一些准备工作,如初始化进度条的最大值等。

上段代码中还涉及到一下几个变量:mStatus、mWorker、sExecutor、mFuture。

(1)、关于mStatus,通过以下代码可以发现可以发现Status是个枚举类,而mStatus代表AsyncTask的状态。

AsyncTask的初始状态为PENDING,代表待定状态,

RUNNING代表执行状态,

FINISHED代表结束状态,

这几种状态在AsyncTask一次生命周期内的很多地方被使用,非常重要。

 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,
}

(2)、关于sExecutor,通过一下代码可以发现sExecutor是一个线程池,通过分析该线程池的构造方法可以看出来:

该线程池中的线程数量是CORE_POOL_SIZE=5;

该线程池所允许的最大数量是MAXMUM_POOL_SIZE=128;

该线程中激活的线程数量是KEEP_ALIVE=10;

Keep_Alive_Time的时间单位是TimeUnit.Seconds;执行前保持任务的队列是sWorkQueue;

创建新线程时使用的工厂是sThreadFactory。

    private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 10; private static final BlockingQueue<Runnable> sWorkQueue =
new LinkedBlockingQueue<Runnable>(10); 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());
}
}; private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);

(3)、关于mWorker,实际上是AsyncTask的一个的抽象内部类的实现对象实例。

它实现了Callable<Result>接口中的call()方法,在call()方法中调用了doInBackground()方法,

而doInBackgroud()方法运行在子线程中,负责执行耗时操作。相关代码如下:

        mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return doInBackground(mParams);
}
};

    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}

(4)、关于mFuture,相关代码如下:

        mFuture = new FutureTask<Result>(mWorker) {
@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) {
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 = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
}
};

通过上面代码可以发现,mFuture实例对象的done()方法中,如果捕捉到了CancellationException类型的异常,则发送一条“MESSAGE_POST_CANCEL”的消息;如果顺利执行,则发送一条“MESSAGE_POST_RESULT”的消息,而消息都与一个sHandler对象关联。

这个sHandler实例实际上是AsyncTask内部类InternalHandler的实例,而InternalHandler正是继承了Handler,下面我们来分析一下它的相关代码:

    private static final int MESSAGE_POST_RESULT = 0x1;
private static final int MESSAGE_POST_PROGRESS = 0x2;
private static final int MESSAGE_POST_CANCEL = 0x3; private static final InternalHandler sHandler = new InternalHandler();
    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;
}
}
}

通过上面的代码可以发现,在处理消息时,

遇到“MESSAGE_POST_RESULT”时,它会调用AsyncTask中的finish()方法;

遇到“MESSAGE_POST_PROGRESS”时,它会调用AsyncTask中的onProgressUpdate()方法;

遇到“MESSAGE_POST_CANCLE”时,它会调用AsyncTask中的onCancelled()方法。

现在我们来看看finish()方法,通过查看代码可以发现原来finish()方法是负责调用onPostExecute(Result result)方法显示结果并改变任务状态为FINISHED。

    private void finish(Result result) {
if (isCancelled()) result = null;
onPostExecute(result);
mStatus = Status.FINISHED;
}

==================================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址:http://blog.csdn.net/ouyang_peng

==================================================================================================

附录:AsyncTask源代码:

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package android.os; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.CancellationException;
import java.util.concurrent.atomic.AtomicInteger; /**
* <p>AsyncTask enables proper and easy use of the UI thread. This class allows to
* perform background operations and publish results on the UI thread without
* having to manipulate threads and/or handlers.</p>
*
* <p>An asynchronous task is defined by a computation that runs on a background thread and
* whose result is published on the UI thread. An asynchronous task is defined by 3 generic
* types, called <code>Params</code>, <code>Progress</code> and <code>Result</code>,
* and 4 steps, called <code>begin</code>, <code>doInBackground</code>,
* <code>processProgress</code> and <code>end</code>.</p>
*
* <h2>Usage</h2>
* <p>AsyncTask must be subclassed to be used. The subclass will override at least
* one method ({@link #doInBackground}), and most often will override a
* second one ({@link #onPostExecute}.)</p>
*
* <p>Here is an example of subclassing:</p>
* <pre class="prettyprint">
* private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
* protected Long doInBackground(URL... urls) {
* int count = urls.length;
* long totalSize = 0;
* for (int i = 0; i < count; i++) {
* totalSize += Downloader.downloadFile(urls[i]);
* publishProgress((int) ((i / (float) count) * 100));
* }
* return totalSize;
* }
*
* protected void onProgressUpdate(Integer... progress) {
* setProgressPercent(progress[0]);
* }
*
* protected void onPostExecute(Long result) {
* showDialog("Downloaded " + result + " bytes");
* }
* }
* </pre>
*
* <p>Once created, a task is executed very simply:</p>
* <pre class="prettyprint">
* new DownloadFilesTask().execute(url1, url2, url3);
* </pre>
*
* <h2>AsyncTask's generic types</h2>
* <p>The three types used by an asynchronous task are the following:</p>
* <ol>
* <li><code>Params</code>, the type of the parameters sent to the task upon
* execution.</li>
* <li><code>Progress</code>, the type of the progress units published during
* the background computation.</li>
* <li><code>Result</code>, the type of the result of the background
* computation.</li>
* </ol>
* <p>Not all types are always used by an asynchronous task. To mark a type as unused,
* simply use the type {@link Void}:</p>
* <pre>
* private class MyTask extends AsyncTask<Void, Void, Void> { ... }
* </pre>
*
* <h2>The 4 steps</h2>
* <p>When an asynchronous task is executed, the task goes through 4 steps:</p>
* <ol>
* <li>{@link #onPreExecute()}, invoked on the UI thread immediately after the task
* is executed. This step is normally used to setup the task, for instance by
* showing a progress bar in the user interface.</li>
* <li>{@link #doInBackground}, invoked on the background thread
* immediately after {@link #onPreExecute()} finishes executing. This step is used
* to perform background computation that can take a long time. The parameters
* of the asynchronous task are passed to this step. The result of the computation must
* be returned by this step and will be passed back to the last step. This step
* can also use {@link #publishProgress} to publish one or more units
* of progress. These values are published on the UI thread, in the
* {@link #onProgressUpdate} step.</li>
* <li>{@link #onProgressUpdate}, invoked on the UI thread after a
* call to {@link #publishProgress}. The timing of the execution is
* undefined. This method is used to display any form of progress in the user
* interface while the background computation is still executing. For instance,
* it can be used to animate a progress bar or show logs in a text field.</li>
* <li>{@link #onPostExecute}, invoked on the UI thread after the background
* computation finishes. The result of the background computation is passed to
* this step as a parameter.</li>
* </ol>
*
* <h2>Threading rules</h2>
* <p>There are a few threading rules that must be followed for this class to
* work properly:</p>
* <ul>
* <li>The task instance must be created on the UI thread.</li>
* <li>{@link #execute} must be invoked on the UI thread.</li>
* <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
* {@link #doInBackground}, {@link #onProgressUpdate} manually.</li>
* <li>The task can be executed only once (an exception will be thrown if
* a second execution is attempted.)</li>
* </ul>
*/
public abstract class AsyncTask<Params, Progress, Result> {
private static final String LOG_TAG = "AsyncTask"; private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 10; private static final BlockingQueue<Runnable> sWorkQueue =
new LinkedBlockingQueue<Runnable>(10); 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());
}
}; 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; private static final InternalHandler sHandler = new InternalHandler(); private final WorkerRunnable<Params, Result> mWorker;
private final FutureTask<Result> mFuture; 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,
} /**
* 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);
}
}; mFuture = new FutureTask<Result>(mWorker) {
@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) {
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 = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
}
};
} /**
* Returns the current status of this task.
*
* @return The current status.
*/
public final Status getStatus() {
return mStatus;
} /**
* Override this method to perform a computation on a background thread. The
* specified parameters are the parameters passed to {@link #execute}
* by the caller of this task.
*
* This method can call {@link #publishProgress} to publish updates
* on the UI thread.
*
* @param params The parameters of the task.
*
* @return A result, defined by the subclass of this task.
*
* @see #onPreExecute()
* @see #onPostExecute
* @see #publishProgress
*/
protected abstract Result doInBackground(Params... params); /**
* Runs on the UI thread before {@link #doInBackground}.
*
* @see #onPostExecute
* @see #doInBackground
*/
protected void onPreExecute() {
} /**
* Runs on the UI thread after {@link #doInBackground}. The
* specified result is the value returned by {@link #doInBackground}
* or null if the task was cancelled or an exception occured.
*
* @param result The result of the operation computed by {@link #doInBackground}.
*
* @see #onPreExecute
* @see #doInBackground
*/
@SuppressWarnings({"UnusedDeclaration"})
protected void onPostExecute(Result result) {
} /**
* Runs on the UI thread after {@link #publishProgress} is invoked.
* The specified values are the values passed to {@link #publishProgress}.
*
* @param values The values indicating progress.
*
* @see #publishProgress
* @see #doInBackground
*/
@SuppressWarnings({"UnusedDeclaration"})
protected void onProgressUpdate(Progress... values) {
} /**
* Runs on the UI thread after {@link #cancel(boolean)} is invoked.
*
* @see #cancel(boolean)
* @see #isCancelled()
*/
protected void onCancelled() {
} /**
* Returns <tt>true</tt> if this task was cancelled before it completed
* normally.
*
* @return <tt>true</tt> if task was cancelled before it completed
*
* @see #cancel(boolean)
*/
public final boolean isCancelled() {
return mFuture.isCancelled();
} /**
* Attempts to cancel execution of this task. This attempt will
* fail if the task has already completed, already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when <tt>cancel</tt> is called,
* this task should never run. If the task has already started,
* then the <tt>mayInterruptIfRunning</tt> parameter determines
* whether the thread executing this task should be interrupted in
* an attempt to stop the task.
*
* @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete.
*
* @return <tt>false</tt> if the task could not be cancelled,
* typically because it has already completed normally;
* <tt>true</tt> otherwise
*
* @see #isCancelled()
* @see #onCancelled()
*/
public final boolean cancel(boolean mayInterruptIfRunning) {
return mFuture.cancel(mayInterruptIfRunning);
} /**
* Waits if necessary for the computation to complete, and then
* retrieves its result.
*
* @return The computed result.
*
* @throws CancellationException If the computation was cancelled.
* @throws ExecutionException If the computation threw an exception.
* @throws InterruptedException If the current thread was interrupted
* while waiting.
*/
public final Result get() throws InterruptedException, ExecutionException {
return mFuture.get();
} /**
* Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result.
*
* @param timeout Time to wait before cancelling the operation.
* @param unit The time unit for the timeout.
*
* @return The computed result.
*
* @throws CancellationException If the computation was cancelled.
* @throws ExecutionException If the computation threw an exception.
* @throws InterruptedException If the current thread was interrupted
* while waiting.
* @throws TimeoutException If the wait timed out.
*/
public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
ExecutionException, TimeoutException {
return mFuture.get(timeout, unit);
} /**
* Executes the task with the specified parameters. The task returns
* itself (this) so that the caller can keep a reference to it.
*
* This method must be invoked on the UI thread.
*
* @param params The parameters of the task.
*
* @return This instance of AsyncTask.
*
* @throws IllegalStateException If {@link #getStatus()} returns either
* {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
*/
public final AsyncTask<Params, Progress, Result> execute(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;
sExecutor.execute(mFuture); return this;
} /**
* This method can be invoked from {@link #doInBackground} to
* publish updates on the UI thread while the background computation is
* still running. Each call to this method will trigger the execution of
* {@link #onProgressUpdate} on the UI thread.
*
* @param values The progress values to update the UI with.
*
* @see #onProgressUpdate
* @see #doInBackground
*/
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;
}
}
}

==================================================================================================

  作者:欧阳鹏  欢迎转载,与人分享是进步的源泉!

  转载请保留原文地址:http://blog.csdn.net/ouyang_peng

==================================================================================================