android 自己实现 AsyncTask
2016-07-29 19:42
716 查看
自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果
这里先介绍Callable,Future以及FutureTask的使用,因为AsyncTask里面需要使用FutureTask,这里给出一篇参考文章:Java并发编程:Callable、Future和FutureTask点击打开链接。
下面是我自己实现的,其中很多参考了 源码,主要实现了其主要逻辑,细节可以直接参考源码。其实现的核心是一个Handler主要是为了在UI线程中来执行onPostExecute(Result result)以及onProgressUpdate(Progress... progress),一个Executor是用来执行WorkRunnable也就是在doInBackgroud(Param...
prarames)中执行的部分,而在doInBackground执行完之后,因为我们使用了FutureTask<Result>,因此可以通过重载其done()函数,该函数是在FutureTask执行完毕之后才会被调用,因此在其中可以通过mFutureTask.get()函数,获取该task执行的结果,也就是onPostExecute(Result result)需要的result,将其通过sendToTarget发送给Handler在UI线程中执行
另外推荐一篇写AsyncTask的文章 http://www.jianshu.com/p/dad0ecb5461e
这里先介绍Callable,Future以及FutureTask的使用,因为AsyncTask里面需要使用FutureTask,这里给出一篇参考文章:Java并发编程:Callable、Future和FutureTask点击打开链接。
下面是我自己实现的,其中很多参考了 源码,主要实现了其主要逻辑,细节可以直接参考源码。其实现的核心是一个Handler主要是为了在UI线程中来执行onPostExecute(Result result)以及onProgressUpdate(Progress... progress),一个Executor是用来执行WorkRunnable也就是在doInBackgroud(Param...
prarames)中执行的部分,而在doInBackground执行完之后,因为我们使用了FutureTask<Result>,因此可以通过重载其done()函数,该函数是在FutureTask执行完毕之后才会被调用,因此在其中可以通过mFutureTask.get()函数,获取该task执行的结果,也就是onPostExecute(Result result)需要的result,将其通过sendToTarget发送给Handler在UI线程中执行
package com.example.renlei.myapplication.handler; import android.os.AsyncTask; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.support.annotation.MainThread; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * Created by renlei * DATE: 16/7/29 * Time: 15:33 */ public abstract class MyAsyncTask<Params, Progress, Result> { /** * 含有的成员变量 */ private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();// private static final int CORE_COUNT = CPU_COUNT + 1; private static final int MAX_COUNT = CPU_COUNT * 2 + 1; private static final int POST_EXECUTE = 0x00001; private static final int PUBLISH_PROGRSS = 0x00002; private final WorkRunnable<Params, Result> mWork; private final FutureTask<Result> mFutureTask; private static final int KEEP_ALIVE = 1; private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128); 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 Executor mExecutor = new ThreadPoolExecutor(CORE_COUNT, MAX_COUNT, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); private static InnerUIHandler mUIHandler; private static Handler getHandler() { synchronized (AsyncTask.class) { if (mUIHandler == null) { mUIHandler = new InnerUIHandler(); } return mUIHandler; } } /** * 构造函数 */ public MyAsyncTask() { /** * 构造函数中初始化 */ mWork = new WorkRunnable<Params, Result>() { @Override public Result call() throws Exception { Result result = doInBackground(paramses); return result; } }; mFutureTask = new FutureTask<Result>(mWork) { @Override protected void done() {/// 线程执行完成之后会执行该函数 super.done(); try { postResult(get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }; } /** * 用来获取futuretask执行完成的结果 * * @return * @throws InterruptedException * @throws ExecutionException */ public final Result get() throws InterruptedException, ExecutionException { return mFutureTask.get(); } private void postResult(Result result) { getHandler().obtainMessage(POST_EXECUTE, new AsyncTaskResult<Result>(this, result)).sendToTarget(); } /** * 可以回调的一些函数 */ @MainThread protected void onPreExecute() { } protected abstract Result doInBackground(Params... params); @MainThread protected void onPostExecute(Result result) { } @MainThread protected void onCancelled() { } @MainThread protected void onProgressUpdate(Progress... progress) { } private static class InnerUIHandler extends Handler { public InnerUIHandler() { super(Looper.getMainLooper());//给handle一个Looper } @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case POST_EXECUTE: AsyncTaskResult result = (AsyncTaskResult) msg.obj; result.myAsyncTask.postResult(result.mData); break; case PUBLISH_PROGRSS: AsyncTaskResult result2 = (AsyncTaskResult) msg.obj; result2.myAsyncTask.onProgressUpdate(result2.mData); break; } } } public final void publishProgress(Progress... progress) { getHandler().obtainMessage(PUBLISH_PROGRSS, new AsyncTaskResult<Progress>(this, progress)).sendToTarget(); } /** * 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, } private volatile Status mStatus = Status.PENDING; public final MyAsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(mExecutor, params); } public final MyAsyncTask<Params, Progress, Result> executeOnExecutor(Executor executor, Params... paramses) { 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(); mWork.paramses = paramses; executor.execute(mFutureTask); return this; } private static abstract class WorkRunnable<Params, Result> implements Callable<Result> { Params[] paramses; } private static class AsyncTaskResult<Data> { MyAsyncTask myAsyncTask; Data[] mData; public AsyncTaskResult(MyAsyncTask myAsyncTask, Data... mData) { this.myAsyncTask = myAsyncTask; this.mData = mData; } } }
另外推荐一篇写AsyncTask的文章 http://www.jianshu.com/p/dad0ecb5461e
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories