在我的《我的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的大纲视图

查看一下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

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

我的Android进阶之旅------>Android中AsyncTask源码分析的更多相关文章

  1. 我的Android进阶之旅------>Android中查看应用签名信息

    一.查看自己的证书签名信息 如上一篇文章<我的Android进阶之旅------>Android中制作和查看自定义的Debug版本Android签名证书>地址:http://blog ...

  2. 我的Android进阶之旅------> Android为TextView组件中显示的文本添加背景色

    通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...

  3. 我的Android进阶之旅------> Android在TextView中显示图片方法

    面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包含图像的文本信息),并简要说明实现方法. 答案:Android SDK支持如下显示富文本信息的方式. 1.使用Tex ...

  4. 我的Android进阶之旅------> Android为TextView组件中显示的文本加入背景色

    通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...

  5. 我的Android进阶之旅------>Android利用温度传感器实现带动画效果的电子温度计

    要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...

  6. 我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(三)Android客户端功能实现

    我的Android进阶之旅------>Android实现用Android手机控制PC端的关机和重启的功能(一)PC服务器端(地址:http://blog.csdn.net/ouyang_pen ...

  7. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之实现游戏逻辑(五)

    在上一篇<我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)>中提到的两个类: GameConf:负责管理游戏的 ...

  8. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)

    正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...

  9. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)

    对于游戏玩家而言,游戏界面上看到的"元素"千变万化:但是对于游戏开发者而言,游戏界面上的元素在底层都是一些数据,不同数据所绘制的图片有所差异而已.因此建立游戏的状态数据模型是实现游 ...

随机推荐

  1. linux下rar包的解压方法

    linux下rar包的解压方法 学习了:https://blog.csdn.net/yonggeit/article/details/72190246?utm_source=itdadao&u ...

  2. centos 6.x Python2.7x安装

    centos 6.x Python2.7x安装 yum install -y gcc gcc-develwget https://www.python.org/ftp/python/2.7.14/Py ...

  3. Java Learning Path(五)资源篇

    Java Learning Path(五)资源篇 1. http://java.sun.com/ (英文) Sun的Java网站,是一个应该经常去看的地方.不用多说. 2.http://www-900 ...

  4. Docker iptables failed: iptables -t nat -A DOCKER -p tcp

    Dokcer网络问题 因为操作或修该过iptables导致docker容器出现如下错误: [root@mysqlserver ~]# docker restart cvnavi-centos-tomc ...

  5. sublime livereload插件

    1.首先在chrome商店下载livereload 安装之后记得在 chrome 的 扩展程序 里面 勾上 允许访问文件地址 2.sublime text 3 中下载插件 Livereload 3.配 ...

  6. TI_DSP_SRIO - package type(包格式)

    1.The type of SRIO packageis determined by the combination of Ftype(format type) and Ttype(transacti ...

  7. zabbix api调用

    zabbix api调用 api能干什么 Zabbix API allows you to programmatically retrieve and modify the configuration ...

  8. git设置全局和单个仓库账号和密码

    Git全局配置和单个仓库的用户名邮箱配置 配置全局仓库的账号和密码 git config --global user.name "userName" //你的用户名 git con ...

  9. printf()与 scanf()

    一直以来就没有认真看过控制台输入输出的格式,现今找了一些材料,分享如下: 1. 格式化规定符     Turbo C2.0提供的格式化规定符如下: ━━━━━━━━━━━━━━━━━━━━━━━━━━ ...

  10. 2017湘潭赛 A题 Determinant (高斯消元取模)

    链接 http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1260 今年湘潭的A题 题意不难 大意是把n*(n+1)矩阵去掉某一列 ...