关闭

Android开发之消息机制详解(2)线程间的通信AsyncTask

263人阅读 评论(0) 收藏 举报

我们如果要执行一个耗时的操作,一般都会开个线程,那么在Android里就有两种方法,一种就是我上篇文章中讲到的用handler+thread,而另外一种就是今天要讲到的AsyncTask。
代码比较简单:

package com.example.test;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;

public class MyActivity extends Activity{
    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        MyAsyncTask asyncTask = new MyAsyncTask();

        if (Build.VERSION.SDK_INT >= 11) {
            asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "url");
        }else{
            asyncTask.execute("url");   
        }
    }

    private String DoSomething(){
        return "";
    }

    private void UpdateUi(String text){

    }

    private void showPressg(int press){

    }
    class MyAsyncTask extends AsyncTask<String, Integer, String>{

        @Override
        protected String doInBackground(String... params) {
            // TODO Auto-generated method stub
            String result;

            return DoSomething();
        }



        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            UpdateUi(result);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            // TODO Auto-generated method stub
            super.onProgressUpdate(values);
            showPressg(values[0]);
        }




    }

}

这里面的各个回调方法 我就不多说了,相信一般大家都懂。
我要重点说下的是一些需要注意的地方:

1.关于开启工作线程 asyncTask.execute(“url”); 这个方法,在3.0以前这个方法是异步的,也就是说几个任务是同时执行的,而3.0以后,这个方法谷歌将这个方法改成同步的了,我们要用asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, “url”);这个来异步开启。

2.asyncTask相对handler+Thread的一个好处就是它内部实现了线程池,可以对空闲线程进行复用。但是它同时存在的线程数量最多是5个,而剩余的任务则会进入任务队列去排队。这同时也是asyncTask的一个缺点,因为排队的任务一旦超过128,则会报异常。

3.asyncTask内部其实也是使用hanlder+Thread实现的,部分源码如下:


    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;
            }
        }
    }

    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
        Params[] mParams;
    }

    @SuppressWarnings({"RawUseOfParameterizedType"})
    private static class AsyncTaskResult<Data> {
        final AsyncTask mTask;
        final Data[] mData;

        AsyncTaskResult(AsyncTask task, Data... data) {
            mTask = task;
            mData = data;
        }
    }

asyncTask的优点就是比较方便,但是不利于对特定任务的管理。

4.综上所诉,当我们需要处理一些比较轻量级的,重复度较高的任务时,可以使用asyncTask,但是如果我们需要处理一些比较复杂,或者对需要对特定的任务进行特定的处理的时候,还是推荐使用handler+Thread,当然,我更推荐使用handler+ThreadPooL,或者自己根据需要实现线程池。

5.还有一点,是handler和asyncTask都存在的一个问题,就是当它们持有activity的对象时,有可能造成内存泄露,这个下一篇讲下handler的优化。

0
0

猜你在找
【套餐】Hadoop生态系统零基础入门
【套餐】嵌入式Linux C编程基础
【套餐】2017软考系统集成项目——任铄
【套餐】Android 5.x顶级视频课程——李宁
【套餐】深度学习入门视频课程——唐宇迪
【直播】广义线性模型及其应用——李科
【直播】从0到1 区块链的概念到实践
【直播】计算机视觉原理及实战——屈教授
【直播】机器学习之凸优化——马博士
【直播】机器学习&数据挖掘7周实训--韦玮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:25095次
    • 积分:552
    • 等级:
    • 排名:千里之外
    • 原创:30篇
    • 转载:0篇
    • 译文:0篇
    • 评论:11条
    最新评论