android 自己实现 AsyncTask

自从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线程中执行

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值