Android异步相关-AsyncTask/HandlerThread/IntentService

AysncTask

AsyncTask本质上是一个Handler和线程池的封装,线程池用来异步处理后台任务,handler用来发送消息进行UI方面的交互
优点:

  • 适合简单短时的异步任务,可以同时爆发数量较大的异步任务(支持线程池,任务队列128个,最多同时并发5个)
  • 过程可控(即onPreExecute、doInBackground、onPostExecute等)

AsyncTask

public final AsyncTask<Params, Progress, Result> execute(Params... params) {  
    return executeOnExecutor(sDefaultExecutor, params);  
}  
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,  
        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;  
    exec.execute(mFuture);  
    return this;  
}  

这里调用onPreExecute后开始触发线程池 ,跑子线程。线程池中最终运行mFuture的run方法,run调用innerRun

void innerRun() {  
    if (!compareAndSetState(READY, RUNNING))  
        return;  
    runner = Thread.currentThread();  
    if (getState() == RUNNING) { // recheck after setting thread  
        V result;  
        try {  
            result = callable.call();  
        } catch (Throwable ex) {  
            setException(ex);  
            return;  
        }  
        set(result);  
    } else {  
        releaseShared(0); // cancel  
    }  
}  

这边的callable.call其实就是调用WorkerRunnable.call

public Result call() throws Exception {  
    mTaskInvoked.set(true);  
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);  
    return postResult(doInBackground(mParams));  
} 

很明显就是在线程内部调用了doInBackground,之后把doInBackground的结果作为参数调用postResult;这里先揭秘下,postResult会利用Handler回到主线程调用onPostExecute

private Result postResult(Result result) {  
    Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,  
            new AsyncTaskResult<Result>(this, result));  
    message.sendToTarget();  
    return result;  
} 
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;  
        }  
    }  
}  

可以看到这边有handleMessage有两个分支一个分支finish最终调用onPostExecute,另一个onProgressUpdate是更新进度的

HandlerThread

HandlerThread本质上就是一个Thread和Looper的封装。与AsyncTask的区别在于,AsyncTask适合短时并发数多的小任务,HandlerThread适合耗时多数据量大的任务。但HandlerThread同时只能执行一个任务,多个任务会以队列的形式串行执行。
优点:

  • 结构清晰,功能定义明确
  • 对于多个后台任务时,简单,清晰

用法

       HandlerThread mHandlerThread = new HandlerThread("MyHandlerThread");
        mHandlerThread.start();
        //HandlerThread内部的Looper,这边的代码会在HandlerThread里的子线程中执行
        Handler handler = new Handler(mHandlerThread.getLooper()){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //这里可以执行异步任务,执行完可调用mMainHandler回到主线程刷新UI
            }
        };
        //发送消息触发HandlerThread的handler,执行异步任务
        handler.sendEmptyMessage(1);
        //这种用法与sendMessage差不多,只不过这边的Message自带里处理Callback即Runnable的处理
        handler.post(new Runnable() {
            @Override
            public void run() {

            }
        });
        //主线程的Looper
        Handler mMainHandler = new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //更新UI
            }
        };
        //清空HandlerThread内部消息
        mHandlerThread.quit();//清空所有消息
        mHandlerThread.quitSafely();//只清空延迟消息

HandlerThread源码

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;
    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }
    protected void onLooperPrepared() {
    }
    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();    //唤醒其他线程的等待锁,这边是为了唤醒getLooper()方法中的等待锁
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }        
    public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }
        // 线程开始,该方法会一直等待Looper对象创建完成才会执行,               
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }    
    public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
    }    
    public boolean quitSafely() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quitSafely();
            return true;
        }
        return false;
    }    
    public int getThreadId() {
        return mTid;
    }
}

源码很短,没有太多难点主要是一些细节处理。

IntentService

IntentService本质上是一个Service和HandlerThread的封装。
优点:

  • IntentService创建独立线程来处理Intent请求
  • IntentService处理请求后会自动停止

注意点:IntentService只能使用bindService,如果用startService来启动的话则onHandleIntent则不会被调用,失去IntenService的 意义,变得跟普通Service一样。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值