Android学习笔记—第五章 进程与线程

第五章 进程与线程

  1. 进程:一个应用程序就是一个进程

    (1)进程的优先级:

    Foreground Process 前台进程

    a. 当前用户正在操作的Activity所在的进程

    b. 绑定了当前用户操作的Activity的service所在的进程

    c. 通过调用了startForeground()方法提升优先级的service所在的进程

    d. 正在调用onCreate()、onStart()、onDestory()方法的service所在的进程

    e. 正在调用onReceiver()方法的BroadcastReceiver所在的进

    Visiable Process 可见进程

    a. 处于暂停状态的Activity所在的进程

    b. 绑定了处于暂停状态的Activity的service所在的进程

    Service Process 服务进程

    通过调用startService()方法启动的service所在的进程

    Background Process 后台进程

    处于停止状态的Activity所在的进程

    Empty Process 空进程

    加速下一个程序的启动

  2. 线程;一个程序内部的顺序控制流

    ANR:Application Not Responding  应用程序未响应

    主线程机制:当main线程执行耗时超过5秒,没有响应下一事件,可能出现ANR

    main线程的作用:UI的创建、更新、事件的处理

    Only the original thread that created a view hierarchy can touch its views

    只有创建了该控件的线程才能去更新这个控件

  3. Handler消息传递机制:实现在新创建的线程中操作UI界面

    (1)MessageQueue消息队列:

    MessageQueue用于存放Message,存放的Message按照FIFO(先进先出)的原则执行。MessageQueue被封装到Looper里面

    (2)Looper循环者

    在Android中,一个线程对应一个Looper对象,一个Looper对象对应一个MessageQueue。Looper对象用来为一个线程开启一个消息循环,用来操作MessageQueue。默认情况下,Android新创建的线程是没有开启消息循环的(主线程除外)。要想在非主线程中创建Handler对象,首先需要用Looper类的prepare()方法初始化一个Looper对象,然后创建Handler对象,再使用Looper类的loop()方法,启动Looper,从消息队列里获取和处理消息。例如:

    public class LooperThread extends Thread{

        public Handler handler;

        @Override

        public void run(){

            super.run();

            Looper.prepare();

            //实例化一个Handler对象

            handler = new Handler(){

                public void handleMessage(Message msg){

                    Log.i("Looper",String.valueOf(msg.what));

                } 

            };

            Message message = handler.obtainMessage();  //获取消息

            message.what = 0x11;    //设置Message的what属性的值

            handler.sendMessage(message);   //发送消息

            Looper.loop();        //启动Looper

        }

    }

    Looper类提供的常用方法

    a. prepare():用于初始化Looper

    b. loop():调用loop()方法后,Looper线程开始真正工作,它会从消息队列里获取消息和处理消息

    c. myLooper():可以获取当前线程的Looper对象

    d. getThread();用于获取Looper对象所属的线程

    e. quit():用于结束Looper循环

    备注:写在Looper.loop()之后的代码不会被执行,这个函数内部是一个循环,当调用Handler.getLooper().quit()方法后,loop()方法才会终止,其后面的代码才能得以运行。

    (3)Handler消息处理类

    Handler允许发送和处理Message或Runnable对象到其所在的线程的MessageQueue中。Handler的主要作用有:

    a. 将Message或Runnable应用post()方法或sendMessage()方法发送到MessageQueue中,在发送时可以指定延迟时间、发送时间或要携带的Bundle数据。当MessageQueue循环到该Message时,调用相应的Handler对象的handlerMessage()方法对其进行处理。

    b. 在子线程和主线程进行通信,即在工作线程中与UI线程进行通信。

    备注:在一个线程中,只能有一个Looper和MessageQueue,但是,可以有多个Handler,且这些Handler可以共享同一个Looper和MessageQueue。

    Handler类同的发送和处理消息的常用方法有:

    a. handleMessage(Message msg):处理消息的方法。通常重写该方法来处理消息,在发送消息时,该方法会自动回调。

    b. post(Runnable r):立即发送Runnable对象,该Runnable对象最后将被封装成Message对象。

    c. postAtTime(Runnable r,long uptimeMillis):定时发送Runnable对象

    d. postDelayed(Runnable r,long delayMillis):延迟delayMillis毫秒发送Runnable对象

    e. sendEmptyMessage(int what):发送空消息

    f. sendMessage(Message msg):立即发送消息

    g. sendMessageAtTime(Message msg, long uptimeMillis):定时发送消息

    h. sendMessageDelayed(Message msg, long delayMillis):延迟多少毫秒发送消息

    (4)Message消息类

    Message被存放在MessageQueue中,一个MessageQueue中可以包含多个Message对象。每个Message对象可以通过Message.obtain()或者Handler.obtainMessage()方法获得。Message对象具有如下5个属性:

    a. arg1:int类型,用来存放整型数据

    b. arg2;int类型,用来存放整型数据

    c. obj:Object类型,用来存放发送给接收器的Object类型的任意对象

    d. replyTo;Messenger类型,用来指定此Message发送到何处的可选Message对象

    e. what:int类型,用来指定用户自定义的消息代码,这样接收者可以了解这个消息的信息。

    备注;使用Message类的属性可以携带int型数据,如果要携带其他类型的数据,可以先将要携带的数据保存到Bundle对象中,然后通过Message类的setData()方法将其添加到Message中。

    注意:

    a. 通常情况下,使用Message.obtian()方法或Handler.obtainMessage()方法从消息池中获得空消息对象,以节省资源。

    b. 如果一个Message只需携带简单的int型信息,应优先使用Message.arg1和Message.arg2属性来传递信息,这比用Bundle更省内存。

    c. 尽可能使用Message.what来标识信息,以便用不同方式处理Message。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。