Android 异步消息处理

前言

  • 我们都知道Android的UI线程是不安全,在子线程中更新UI会造成程序崩溃,但是我们有时候确实需要在子线程中进行耗时操作,然后再依据结果更新UI
  • 在学习具体的方法前我们首先看一下Android的异步消息处理机制示意图

    这里写图片描述

  • 我们再来把异步消息处理的整个流程梳理一下:

    1. 首先需要在主线程当中创建一个Handler对象,并重写handleMessage()方法。
    2. 然后当子线程中需要进行UI操作时,就创建一个Message对象,并通过Handler将这条消息发送出去。
    3. 之后这条消息会被添加到MessageQueue的队列中等待被处理
    4. 而Looper则会一直尝试从MessageQueue中取出待处理消息,最后分发回Handler的handlerMessage()方法中。

方法总结

1.使用Handler

在主线程中创建Handler:

        public android.os.Handler handler=new android.os.Handler(){
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what){
                    case UPDATE_TEXT:
                        textView.setText(msg.obj.toString());
                        break;
                    default:
                        break;
                }
            }
        };

在子线程中调用sendMessage方法更新UI
注意:这里的sendHttpRequest是OkHttp提供的回调接口,是在子线程中运行的

      HttpUtil.sendHttpRequest(address,new okhttp3.Callback(){
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String responseData = response.body().string();
                    Message message = new Message();
                    message.what=UPDATE_TEXT;
                    message.obj=responseData;
                    handler.sendMessage(message);
                }

                @Override
                public void onFailure(Call call, IOException e) {
                    e.printStackTrace();
                }
            });
2.使用runInUiThread()方法
  • 这表面看起来是一个很简单的方法,但其实它就是一个异步消息处理机制的接口封装,背后的实现原理其实和上图的描述是一样的。

    private void showResponse(final String response){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                textView.setText(response);
            }
        });
    }
    
3.使用AsyncTask
  • 这种方法看起来需要编写更多的代码,但是实际上在语义方面会更加清晰

            @Override
            protected void onPreExecute() {
                //这个方法会在后台任务开始执行之前调用,用于进行一个界面上的初始化操作
                super.onPreExecute();
            }
    
            @Override
            protected Object doInBackground(Object[] params) {
                //这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。
                //任务一旦完成就可以通过return语句来将任务的执行结果返回。
                //注意:在这个方法中是不可以进行UI操作的。
                return null;
            }
    
            @Override
            protected void onProgressUpdate(Object[] values) {
                 //当调用publishProgress()方法传入当前的下载进度时。
                 //onProgressUpdate()方法就会很快被调用,在这里就可以就行UI操作了
                super.onProgressUpdate(values);
            }
    
            @Override
            protected void onPostExecute(Object o) {
                //当doInBackground()方法返回时,onPostExecute()方法就会很快的被调用
                //执行一些任务的收尾工作
                super.onPostExecute(o);
            }
    

后记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值