美文网首页
Android异步线程AsyncTask封装

Android异步线程AsyncTask封装

作者: hai_phon | 来源:发表于2017-05-01 22:05 被阅读0次

    最近工作用到很多线程,现公司代码中用的最多的就是Thread+Handler,简直不要再麻烦,一堆的sendMessage()和一堆的handleMessage(),每个类用到的地方都要重新复制一遍;想起前公司老大用的封装好的AsyncTask,对比起来太舒服了,于是整理出来,顺便分享给大家,合适的就拿去哦。


    //AsyncTaskUtils.java源码
    
    package com.test.utils;
    
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.os.AsyncTask;
    import android.text.TextUtils;
    import android.util.Log;
    
    
    import java.util.concurrent.Callable;
    
    /**
     * AsyncTaskUtils.java
     * @author haiphon.huang
     * @description 异步线程调用工具类,其中返回值都是泛型,所以成功和失败想要哪种类型在调用的时候就用哪种类型。
     * @author Created by haiphon.huang 2017.5.1
     * 注意:其中Callable 是android-23里面自带的
     */
    public class AsyncTaskUtils {
        /**
         * @param pContext 上下文
         * @param pTitleResourceID xml里面的 R.string.* 类型的参数,显示为加载框标题,null则没有加载标题提示
         * @param pMessageResourceID xml里面的 R.string.* 类型的参数,显示为加载框内容,null则没有加载内容提示
         * @param pCallable 耗时代码写在此
         * @param PCallBack 任务成功/失败的回调函数,自己根据返回值进行判断处理,自己根据返回值进行判断处理
         * @param <T> 默认是false,代表不能取消该任务
         */
        public static <T> void doAsync(final Context pContext,
                                       final int pTitleResourceID, final int pMessageResourceID,
                                       final Callable<T> pCallable, final Callback<T> PCallBack) {
            AsyncTaskUtils.doAsync(pContext, pTitleResourceID, pMessageResourceID,
                    pCallable, PCallBack, null, false);
        }
    
        /**
         * @param pContext 上下文
         * @param pTitle 传递String/CharSequence类型参数,显示为加载框标题,null则没有加载标题提示
         * @param pMessage 传递String/CharSequence类型参数,显示为加载框内容,null则没有加载内容提示
         * @param pCallable 耗时代码写在此
         * @param pFailedCallback 任务成功/失败的回调函数,自己根据返回值进行判断处理
         * @param <T> 默认是false,代表不能取消该任务
         */
        public static <T> void doAsync(final Context pContext,
                                       final CharSequence pTitle, final CharSequence pMessage,
                                       final Callable<T> pCallable, final Callback<T> pFailedCallback) {
            AsyncTaskUtils.doAsync(pContext, pTitle, pMessage, pCallable, pFailedCallback,
                    null, false);
        }
    
        /**
         * @param pContext 上下文
         * @param pTitleResourceID xml里面的 R.string.* 类型的参数,显示为加载框标题,null则没有加载标题提示
         * @param pMessageResourceID xml里面的 R.string.* 类型的参数,显示为加载框内容,null则没有加载内容提示
         * @param pCallable 耗时代码写在此
         * @param pFailedCallback 任务成功/失败的回调函数,自己根据返回值进行判断处理
         * @param pCancelable 传递true代表可以取消该任务,false代表不能取消该任务
         */
        public static <T> void doAsync(final Context pContext,
                                       final int pTitleResourceID, final int pMessageResourceID,
                                       final Callable<T> pCallable, final Callback<T> pFailedCallback,
                                       final boolean pCancelable) {
            AsyncTaskUtils.doAsync(pContext, pTitleResourceID, pMessageResourceID,
                    pCallable, pFailedCallback, null, pCancelable);
        }
    
        /**
         * @param pContext 上下文
         * @param pTitle 传递String/CharSequence类型参数,显示为加载框标题,null则没有加载标题提示
         * @param pMessage 传递String/CharSequence类型参数,显示为加载框内容,null则没有加载内容提示
         * @param pCallable 耗时代码写在此
         * @param pFailedCallback 任务成功/失败的回调函数,自己根据返回值进行判断处理
         * @param pCancelable 传递true代表可以取消该任务,false代表不能取消该任务
         */
        public static <T> void doAsync(final Context pContext,
                                       final CharSequence pTitle, final CharSequence pMessage,
                                       final Callable<T> pCallable, final Callback<T> pFailedCallback,
                                       final boolean pCancelable) {
            AsyncTaskUtils.doAsync(pContext, pTitle, pMessage, pCallable, pFailedCallback,
                    null, pCancelable);
        }
    
        /**
         * @param pContext 上下文
         * @param pTitleResourceID xml里面的 R.string.* 类型的参数,显示为加载框标题,null则没有加载标题提示
         * @param pMessageResourceID xml里面的 R.string.* 类型的参数,显示为加载框内容,null则没有加载内容提示
         * @param pCallable 耗时代码写在此
         * @param pFailedCallback 任务成功/失败的回调函数,自己根据返回值进行判断处理
         * @param pExceptionCallback  任务参数错误或者其他导致的异常回调
         * @param <T> 默认是false,代表不能取消该任务
         */
        public static <T> void doAsync(final Context pContext,
                                       final int pTitleResourceID, final int pMessageResourceID,
                                       final Callable<T> pCallable, final Callback<T> pFailedCallback,
                                       final Callback<Exception> pExceptionCallback) {
            AsyncTaskUtils.doAsync(pContext, pTitleResourceID, pMessageResourceID,
                    pCallable, pFailedCallback, pExceptionCallback, false);
        }
    
        /**
         * @param pContext 上下文
         * @param pTitle xml里面的 R.string.* 类型的参数,显示为加载框标题,null则没有加载标题提示
         * @param pMessage xml里面的 R.string.* 类型的参数,显示为加载框内容,null则没有加载内容提示
         * @param pCallable 耗时代码写在此
         * @param pFailedCallback 任务成功/失败的回调函数,自己根据返回值进行判断处理
         * @param pExceptionCallback  任务参数错误或者其他导致的异常回调
         * @param <T> 默认是false,代表不能取消该任务
         */
        public static <T> void doAsync(final Context pContext,
                                       final CharSequence pTitle, final CharSequence pMessage,
                                       final Callable<T> pCallable, final Callback<T> pFailedCallback,
                                       final Callback<Exception> pExceptionCallback) {
            AsyncTaskUtils.doAsync(pContext, pTitle, pMessage, pCallable, pFailedCallback,
                    pExceptionCallback, false);
        }
    
        /**
         * @param pContext 上下文
         * @param pTitle xml里面的 R.string.* 类型的参数,显示为加载框标题,null则没有加载标题提示
         * @param pMessage xml里面的 R.string.* 类型的参数,显示为加载框内容,null则没有加载内容提示
         * @param pCallable 耗时代码写在此
         * @param pFailedCallback 任务成功/失败的回调函数,自己根据返回值进行判断处理
         * @param pExceptionCallback  任务参数错误或者其他导致的异常回调
         * @param pCancelable 传递true代表可以取消该任务,false代表不能取消该任务
         */
        public static <T> void doAsync(final Context pContext,//2 4 6
                                       final CharSequence pTitle, final CharSequence pMessage,
                                       final Callable<T> pCallable, final Callback<T> pFailedCallback,
                                       final Callback<Exception> pExceptionCallback,
                                       final boolean pCancelable) {
            if (TextUtils.isEmpty(pTitle) && TextUtils.isEmpty(pMessage)) {
                doAsync(pCallable, pFailedCallback, pExceptionCallback);
            } else {
                doAsyncTip(pContext, pTitle, pMessage, pCallable, pFailedCallback,
                        pExceptionCallback, pCancelable);
            }
        }
    
        /**
         * @param pContext 上下文
         * @param pTitleResourceID xml里面的 R.string.* 类型的参数,显示为加载框标题,null则没有加载标题提示
         * @param pMessageResourceID xml里面的 R.string.* 类型的参数,显示为加载框内容,null则没有加载内容提示
         * @param pCallable 耗时代码写在此
         * @param pFailedCallback 任务成功/失败的回调函数,自己根据返回值进行判断处理
         * @param pExceptionCallback  任务参数错误或者其他导致的异常回调
         * @param pCancelable 传递true代表可以取消该任务,false代表不能取消该任务
         */
        public static <T> void doAsync(final Context pContext,//1 3 5
                                       final int pTitleResourceID, final int pMessageResourceID,
                                       final Callable<T> pCallable, final Callback<T> pFailedCallback,
                                       final Callback<Exception> pExceptionCallback,
                                       final boolean pCancelable) {
            AsyncTaskUtils.doAsync(pContext, pContext.getString(pTitleResourceID),
                    pContext.getString(pMessageResourceID), pCallable, pFailedCallback,
                    pExceptionCallback, pCancelable);
        }
    
        /**
         * @param pContext 上下文
         * @param pTitle 传递String/CharSequence类型参数,显示为加载框标题,null则没有加载标题提示
         * @param pMessage 传递String/CharSequence类型参数,显示为加载框内容,null则没有加载内容提示
         * @param pCallable 耗时代码写在此
         * @param pFailedCallback 任务成功/失败的回调函数,自己根据返回值进行判断处理
         * @param pExceptionCallback  任务参数错误或者其他导致的异常回调
         * @param pCancelable 传递true代表可以取消该任务,false代表不能取消该任务
         */
        private static <T> void doAsyncTip(final Context pContext,
                                           final CharSequence pTitle, final CharSequence pMessage,
                                           final Callable<T> pCallable, final Callback<T> pFailedCallback,
                                           final Callback<Exception> pExceptionCallback,
                                           final boolean pCancelable) {
            final ProgressDialog mPD = new ProgressDialog(pContext);
            try {
                mPD.setMessage(pMessage);
                if (!TextUtils.isEmpty(pTitle)) {
                    mPD.setTitle(pTitle);
                }
                mPD.setCancelable(pCancelable);
                mPD.setIndeterminate(true);
                mPD.show();
                if (pCancelable) {
                    mPD.setOnCancelListener(new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(final DialogInterface pDialogInterface) {
                            pExceptionCallback.onCallback(new Exception());
                            pDialogInterface.dismiss();
                        }
                    });
                }
            } catch (Exception e) {
                mPD.hide();
                mPD.cancel();
                mPD.dismiss();
                e.printStackTrace();
            }
    
            new AsyncTask<Void, Void, T>() {
    
                private Exception mException = null;
    
                @Override
                public T doInBackground(final Void... params) {
                    try {
                        return pCallable.call();
                    } catch (final Exception e) {
                        this.mException = e;
                    }
                    return null;
                }
    
                @Override
                public void onPostExecute(final T result) {
                    try {
                        mPD.hide();
                        mPD.cancel();
                        mPD.dismiss();
                    } catch (final Exception e) {
                        Log.e("Error", e.getMessage(), e);
                        // Debug.e("Error", e);
                    }
    
                    if (this.isCancelled()) {
                        this.mException = new Exception();
                    }
    
                    if (this.mException == null) {
                        if (pFailedCallback != null) {
                            pFailedCallback.onCallback(result);
                        }
                    } else {
                        if (pExceptionCallback == null) {
                            Log.e("Error", mException.getMessage(), mException);
                            // Debug.e("Error", this.mException);
                        } else {
                            pExceptionCallback.onCallback(this.mException);
                        }
                    }
                }
            }.execute((Void[]) null);
    
        }
    
    
        public static <T> void doAsync(final Callable<T> pCallable,
                                       final Callback<T> pFailedCallback,
                                       final Callback<Exception> pExceptionCallback) {
            new AsyncTask<Void, Integer, T>() {
                private Exception mException = null;
    
                @Override
                public T doInBackground(final Void... params) {
                    try {
                        return pCallable.call();
                    } catch (final Exception e) {
                        this.mException = e;
                    }
                    return null;
                }
    
                @Override
                public void onPostExecute(final T result) {
    
                    if (this.isCancelled()) {
                        this.mException = new Exception();
                    }
    
                    if (this.mException == null) {
                        if (pFailedCallback != null) {
                            try {
                                pFailedCallback.onCallback(result);
                            } catch (Exception e) {
                                if (pExceptionCallback == null) {
                                    Log.e("Error", e.getMessage(), e);
                                    // Debug.e("Error", this.mException);
                                } else {
                                    pExceptionCallback.onCallback(e);
                                }
                            }
                        }
                    } else {
                        if (pExceptionCallback == null) {
                            Log.e("Error", mException.getMessage(), mException);
                            // Debug.e("Error", this.mException);
                        } else {
                            pExceptionCallback.onCallback(this.mException);
                        }
                    }
                }
            }.execute((Void[]) null);
        }
    
        /**
         * @author jacky.huang
         * @version 2.0.2  2013-2-22
         * @name Callback.java.java
         * @description <回调>
         */
        public interface Callback<T> {
    
            public void onCallback(final T pCallbackValue);
        }
    }
    

    上面就是AsyncTaskUtils.java整个工具类的内容,可能代码有点多,不过你仔细观察一下他重载方法多了一点而已,Android很多源码也这么写,最简单的例子就是TextView的setText(CharSequence charSequence)和setText(int resId),下面是调用的demo

    /**
         * 初始化或者重载数据
         **/
        private void loadData() {
            ActivityUtils.doAsync(mContext, R.string.nullvalue, R.string.loading, new Callable<ProjectModel>() {
                @Override
                public ProjectModel call() throws Exception {//这里手动抛出异常
                    ProjectModelBiz projectBiz = new ProjectModelBiz(ProjectDetailActivity.this);
                    if (isLevelOne) {
                        return projectBiz.getProjectDetail(subjectID);
                    } else {
                        return projectBiz.getSubProjectDetail(subjectID);
                    }
                }
            }, new Callback<ProjectModel>() {
                @Override
                public void onCallback(ProjectModel model) {
                    //通过这个返回值判断成功还是失败。
                    mModel = model;
                    if (model == null || StringHelper.isEmpty(model.getItem_flowto())) {
                        //失败操作...
                    } else {
                        //成功操作...
                    }
                }
            }, new Callback<Exception>() {
                @Override
                public void onCallback(Exception pCallbackValue) {
                    //抛出异常
                    pCallbackValue.printStackTrace();
                }
            }, true);
        }
    

    第一个参数要手动抛出异常

    @Override
                public ProjectModel call() throws Exception {//这里手动抛出异常
                   //...
                }
    

    因为源码中他的回调函数就是这样的:

     */
    public interface Callable<V> {
        /**
         * Computes a result, or throws an exception if unable to do so.
         *
         * @return computed result
         * @throws Exception if unable to compute a result
         */
        V call() throws Exception;
    }
    
    

    相关文章

      网友评论

          本文标题:Android异步线程AsyncTask封装

          本文链接:https://www.haomeiwen.com/subject/mlpqtxtx.html