多线程应用篇

上篇文章介绍了多线程基础内容,这里来讲一讲多线程的表现形式,它有哪些具体的应用。

  • AsyncTask
  • HandlerThread
  • IntentService

一. AsyncTask

1.定义

一个轻量级的异步任务类,是抽象的泛型类,即使用时需实现子类。

public abstract class AsyncTask<Params, Progress, Result> {
...
}

三个泛型参数:

Params:表示执行AsyncTask需要传入的参数的类型。

Progress:表示后台任务执行的进度。

Result:表示后台任务返回的结果的类型。

注意:若没有传递具体的参数,这三个泛型参数都可以使用void

2.作用

(1)实现多线程,在子线程中执行任务,如做耗时操作。

(2)异步通信,消息传递,实现子线程和主线程之间的通信,即将子线程的执行结果传递给主线程,从而在主线程中做相关的UI操作。

3.优点

(1)方便实现异步通信,不需要使用“Thread + Handler”的复杂组合。

(2)节省资源,采用线程池的缓存线程+复用线程,避免了频繁创建线程和销毁线程所带来的系统资源开销。

4.缺点

AsyncTask不太适用于特别耗时的后台任务,而是建议使用线程池。

5.核心方法

(1)onPreExecute():运行在主线程,在异步任务执行之前调用,可做一些初始化操作。

(2)doInBackground(Params… params):运行在子线程,用于处理所有耗时任务,若需更新UI需调用publishProgress(Progress… values)方法。若任务一旦完成,就通过return把任务执行结果返回,如果Result被指定为void,则可不返回执行结果。

(3)onProgressUpdate(Progress… values):运行在主线程,在后台任务中调用publishProgress(Progress… values)之后该方法会被调用。可利用方法中携带的参数如Progress对UI进行更新。

(4)onPostExecute(Result result):运行在主线程,在异步任务执行完毕并通过return语句返回时被调用,可以利用方法中返回的数据对UI进行操作。

(5)onCancelled():运行在主线程,当异步任务被取消时调用。

(6)execute(Params…params):在主线程调用,表示开启一个异步任务。

(7)cancel(boolean mayInterruptIfRunning):在主线程调用,表示停止一个异步任务。

6.自定义AsyncTask

简单模拟一个下载任务,代码如下:

public class TaskActivity extends AppCompatActivity {

    private Button startBt;
    private TextView text;
    private ProgressBar progressBar;
    private Button cancelBt;
    private DownLoadTask downLoadTask;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_task);
        startBt = findViewById(R.id.button);
        text = findViewById(R.id.text);
        progressBar = findViewById(R.id.progress_bar);
        cancelBt = findViewById(R.id.cancel);

        downLoadTask = new DownLoadTask();

        startBt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //同一个AsyncTask实例对象只能执行1次,若执行第2次将会抛出异常
                downLoadTask.execute();
            }
        });

        cancelBt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                downLoadTask.cancel(true);
            }
        });

    }

    public class DownLoadTask extends AsyncTask<String,Integer,String>{

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            text.setText("加载中...");
        }

        @Override
        protected String doInBackground(String... strings) {

            int count = 0;
            int length = 1;
            while (count < 99){
                count += length;
                publishProgress(count);
                //模拟耗时任务
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            progressBar.setProgress(values[0]);
            text.setText("loading..."+values[0]+"%");
        }

        @Override
        protected void onPostExecute(String s) {
            text.setText("加载完毕");
        }

        @Override
        protected void onCancelled() {
            text.setText("取消");
            progressBar.setProgress(0);
        }
    }
}

7.AsyncTask工作原理

(1)内部有一个静态的Handler对象即InternalHandler,通过它来发送任务执行的进度以及执行结束等消息。

(2)内部有两个线程池:

a.SerialExecutor:用于任务的排队,默认的是串行的线程池。

b.THREAD_POOL_EXECUTOR:用于真正处理任务。

(3)排队执行的过程:

a.把参数Params封装成一个FutureTask对象,相当于Runnable。

b.调用SerialExecutor.execute()将FutureTask插入到任务队列tasks。

c.若没有正在执行的AsyncTask任务,则会执行下一个AsyncTask任务,执行完毕后继续执行其他的任务直至所有的任务都执行完成,即默认串行方式执行任务。

二.HandlerThread

HandlerThread是个线程类,它继承Thread类,封装了Handler类,所以与普通的的Thread不同,它具有消息循环的效果。

1.具体实现

(1)实例化一个HandlerThread对象,参数是该线程名称。

(2)通过Handler.start()开启线程。

(3)实例化一个Handler对象并传入HandlerThread中的looper对象,使得与HandlerThread绑定。

(4)通过Handler向消息队列发送消息。

(5)通过HandlerThread.quit()或者HandlerThread.quitSafely()结束线程。

代码示例:

public class HandlerThreadActivity extends AppCompatActivity {

    private HandlerThread myHandler;
    private String TAG = "HandlerThreadActivity==";
    private Handler handler;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handlerthread);
        //第一步,创建HandlerThread
        myHandler = new HandlerThread("myHandler");
        //第二步,启动HandlerThread
        myHandler.start();
        //第三步,创建Handler,并绑定HandlerThread
        handler = new Handler(myHandler.getLooper()){
            @Override
            public void handleMessage(@NonNull Message msg) {
                int what = msg.what;
                String message = (String) msg.obj;
                switch (what) {
                    case 0:
                        Log.d(TAG,message);
                        break;
                    case 1:
                        Log.d(TAG,message);
                        break;
                }

            }
        };
        //第四步,主线程发送消息
        Message message = new Message();
        message.what = 0;
        message.obj = "主线程消息";
        handler.sendMessage(message);
        //子线程发送消息
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 1;
                message.obj = "子线程消息";
                handler.sendMessage(message);
            }
        }).start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //第五步,停止HandlerThread
        myHandler.quit();
    }
}

三.IntentService

IntentService在基础篇Service中做了介绍,这里就不说了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值