zoukankan      html  css  js  c++  java
  • 【Android】用HandlerThread模拟AsyncTask功能(ThreadTask)

    前言

    AsyncTask是个好东西,能处理绝大多数应用线程和更新UI的任务,由于其内部使用了静态线程池,如果你有一堆异步任务(例如全局定时更新数据、同一个Activity中多个AsyncTask同时执行)其中有不能马上执行完的情况(例如网络请求超时),那就糟了,其他任务都还等着呢,就会出现任务卡住的情况。此时就需要直接上Thread了,这里参考AsyncTask的API封装了一个ThreadTask,便于必要时代码替换,欢迎交流!

    声明

    欢迎转载,但请保留文章原始出处:)
    博客园:http://www.cnblogs.com
    农民伯伯: http://over140.cnblogs.com

    正文

    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.Looper;
    import android.os.Message;

    public abstract class ThreadTask<Params, Progress, Result> {

        private HandlerThread mHandlerThread;
        private TaskHandler mHandler;
        private TaskHandler mUiHandler;
        private Params[] mParams;

        public ThreadTask() {
            mHandlerThread = new HandlerThread("ThreadTask", android.os.Process.THREAD_PRIORITY_BACKGROUND);
            mHandlerThread.start();
            mHandler = new TaskHandler(mHandlerThread.getLooper());
            mUiHandler = new TaskHandler(Looper.getMainLooper());
        }

        protected abstract Result doInBackground(Params... params);

        protected void onPreExecute() {
        }

        protected void onProgressUpdate(Progress... values) {
        }

        protected final void publishProgress(Progress... values) {
            mUiHandler.obtainMessage(MESSAGE_PROGRESS, values).sendToTarget();
        }

        protected void onPostExecute(Result result) {
        }

        public final boolean isCancelled() {
            return mHandlerThread.isInterrupted();
        }

        public final void cancel(boolean mayInterruptIfRunning) {
            if (!mHandlerThread.isInterrupted()) {
                try {
                    mHandlerThread.quit();
                    mHandlerThread.interrupt();
                } catch (SecurityException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            onCancelled();
        }

        protected void onCancelled() {
        }

        public void execute(Params... params) {
            mParams = params;
            onPreExecute();
            mHandler.sendEmptyMessage(MESSAGE_INBACKGROUND);
        }

        private static final int MESSAGE_INBACKGROUND = 0;
        private static final int MESSAGE_POSTEXECUTE = 1;
        private static final int MESSAGE_PROGRESS = 2;

        private class TaskHandler extends Handler {

            public TaskHandler(Looper looper) {
                super(looper);
            }

            @SuppressWarnings("unchecked")
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                case MESSAGE_INBACKGROUND:
                    mUiHandler.obtainMessage(MESSAGE_POSTEXECUTE, doInBackground(mParams)).sendToTarget();
                    break;
                case MESSAGE_POSTEXECUTE:
                    onPostExecute((Result) msg.obj);
                    mHandlerThread.quit();
                    break;
                case MESSAGE_PROGRESS:
                    onProgressUpdate((Progress[]) msg.obj);
                    break;
                }
            }
        }
    }

    代码说明:

    由于onPreExecute和onPostExecute都在在主线程执行,又要保证执行的顺序,所以采用Handler来控制执行顺序,根据Loop的不同,Handler能切换在子线程中执行代码还是在主线程中执行代码。

     

    文章

      Android AsyncTask完全解析,带你从源码的角度彻底理解

    后期维护

    2014-08-05  正常流程走完以后忘了调用HandlerThread的quit,代码已经更新。

    结束

    除了不受线程池控制以外,还能被真正的cancel掉(AsyncTask是不能的,只是一个标记),写的有些仓促,难免bug,欢迎反馈!

     

  • 相关阅读:
    Druid 使用 Kafka 将数据载入到 Kafka
    Druid 使用 Kafka 数据加载教程——下载和启动 Kafka
    Druid 集群方式部署 —— 启动服务
    Druid 集群方式部署 —— 端口调整
    Druid 集群方式部署 —— 配置调整
    Druid 集群方式部署 —— 配置 Zookeeper 连接
    Druid 集群方式部署 —— 元数据和深度存储
    Druid 集群方式部署 —— 从独立服务器部署上合并到集群的硬件配置
    Druid 集群方式部署 —— 选择硬件
    Druid 独立服务器方式部署文档
  • 原文地址:https://www.cnblogs.com/over140/p/3607483.html
Copyright © 2011-2022 走看看