当前位置: 移动技术网 > 移动技术>移动开发>Android > Android之多线程与异步浅析

Android之多线程与异步浅析

2020年07月23日  | 移动技术网移动技术  | 我要评论

一、如何理解同步与异步?

           同步:发出动作后,在收到响应前,什么都不能做;

           异步:发出动作后,可以去做其他的事情,不用等待响应。

           通俗的理解上述两个概念:同步就是我喊你去吃饭,我要一直等到你回应;异步就是我喊你去吃饭,我就去了,不管你是否回应。

二、为何要用多线程? 

      Android应用程序在启动时,系统会自动的为该程序生成一个UI线程(即我们常说的主线程),更新页面(UI)的操作都必须在UI线程中进行。与此同时,因为只有一个主线程,在程序运行时,添加控件、点击按钮、网络请求、图片加载等都是在主线程中运行,而这些操作会被放在队列中,顺序执行,每次执行一个事件。这时就会出现一个问题,因为顺序执行且每次只执行一个事件,如果某一个事件执行事件过长(耗时操作),则主线程阻塞,界面卡顿(严重的会报ANR),此时对界面进行操作会出现是否停止响应的提示。这种情况严重影响了操作感。

   为了解决此问题,在程序中使用了多线程,即在UI线程(主线程)之外,新建线程(因多用来处理耗时操作,又称之为工作线程)。将主线程中的耗时操作,如网络请求、文件下载等放入工作线程中进行,避免了因耗时操作将主线程阻塞而引起的ANR问题。因此,为了防止出现ANR,才要用多线程。

此外,使用多线程,可以实现异步,也可以进行多任务(多线程下载)。

三、如何处理多线程之间的通信?

     通过上述对多线程的理解,在多线程开发过程中,我们需要注意:

  • 绝对不能在UI线程中进行耗时操作,以防止阻塞UI线程
  • 不能在UI线程之外更新UI

    由此两点,那我们该如何处理主线程和工作线程之间的通信呢?Android系统为我们提供了两种方式,是Handler机制和AsyncTaskLoader机制。

(一)Handler机制

       主要了解四个类:Looper(循环者)、Handler(消息处理)、Message(消息)、MessageQueue(消息队列)

   Looper: 在Android中,一个线程可以产生一个Looper对象,由它来管理该线程中的消息队列(MessageQueue)。调用Looper的Loop()方法后,就会进入一个无限循环中,发现MessageQueue中存在一条消息,就会取出来并传递到Handler的handleMessage()方法中。Looper对象用来为一个线程开启一个消息循环,用来操作MessgeQueue。默认情况下,Android中新创建的线程是没有开启消息循环的(主线程除外)。

    Handler:主要用于发送和处理消息。发送信息一般使用Handler的sendMessage()方法,发出的消息经过一系列辗转处理后,最终会传递到Handler的handleMessage()方法中。消息处理类(Handler)允许发送和处理Message和Runnable对象到其所在线程的MessageQueue中。它主要有两个作用:

  (1)、将Message应用post()方法或sendMessage()方法发送到MessageQueue中,在发送时可以指定延时发送、发送时间等。当MessageQueue循环到该Message时,调用相应的Handler对象的handlerMessage()方法对其进行处理。

  (2)、在子线程中与主线程进行通信,也就是在工作线程中与UI线程进行通信。另外,在一个线程中只能有一个Looper和MessageQueue,但是可以有多个Handler,而且这些Handler可以共享一个Looper和MessageQueue。

    Message:是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同的线程之间交换数据,如Message的what字段,和arg1,arg2来携带一些整型的数据,使用obj字段携带一个Object对象。消息类(Message)被存放在MessageQueue中,一个MessageQueue中可以包含多个Message对象。每个Message对象可以通过Message.obtain()方法或者Handler.obtainMessage()方法获得。

   MessageQueue:它主要用于存放所有通过Handler发送的消息。这部分消息会一直存在于消息队列中,等待被处理。每个线程中只会有一个MessageQueue对象。 

private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 1:
                    String message = (String) msg.obj;
                    System.out.println("从子线程中传递过来的消息:"+message);
                    //对UI进行更新
                    break;
                default:
                    break;
            }
        }
    };

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Thread(){
            @Override
            public void run() {
                super.run();
                Message msg = new Message();
                msg.what = 1;
                msg.obj = "要发送的消息";
                handler.sendMessage(msg);
            }
        }.start();
}

   (二)AsyncTaskLoader机制:

       创建一个子类继承 AsyncTaskLoader 并实现一个最重要的方法loadInBackground(),该方法和doInBackground()原理相同。下次再补充了!

    

   

 

 

 

 

 

 

 

 

 

本文地址:https://blog.csdn.net/u013970897/article/details/107407876

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网