• Android 消息传递之Bundle的使用——实现object对象传输(一)


    UI更新——消息处理massage  

      对于安卓内部消息得处理,实现对界面UI得更新操作,不能在线程中直接更新ui。至于为什么不能,在学习安卓开发的时候,在线程中操作会使程序崩溃。

    为什么,可以看看诸多大神们的详细介绍。

      安卓内部处理数据更新UI都是耗时的操作,这些耗时操作系统不允许在Activity主线程中进行,必须在其他线程中操作,然后通过发消息的形式通知主线程更新UI,那么我们就要用多线程处理了,massage 消息处理机制。

      下面我们一起分享郭霖Android多线程中消息处理更新UI的介绍。

       通过一个具体的例子来验证一下吧。新建一个 AndroidThreadTest 项目,然后修改 activity_main.xml 中的代码,如下所示:

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2 android:layout_width="match_parent"
     3 android:layout_height="match_parent" >
     4 <Button
     5 android:id="@+id/change_text"
     6 android:layout_width="match_parent"
     7 android:layout_height="wrap_content"
     8 android:text="Change Text" />
     9 <TextView
    10 android:id="@+id/text"
    11 android:layout_width="wrap_content"
    12 android:layout_height="wrap_content"
    13 android:layout_centerInParent="true"
    14 android:text="Hello world"
    15 android:textSize="20sp" />
    16 </RelativeLayout>

    布局文件中定义了两个控件,TextView 用于在屏幕的正中央显示一个 Hello world 字符串,Button 用于改变 TextView 中显示的内容,我们希望在点击 Button 后可以把 TextView中显示的字符串改成 Nice to meet you。接下来 MainActivity 中的代码,如下所示:

     1 public class MainActivity extends Activity implements OnClickListener {
     2     public static final int UPDATE_TEXT = 1;
     3     private TextView text;
     4     private Button changeText;
     5     private Handler handler = new Handler() {
     6         public void handleMessage(Message msg) {
     7             switch (msg.what) {
     8             case UPDATE_TEXT:
     9                 // 在这里可以进行UI 操作
    10                 text.setText("Nice to meet you");
    11                 break;
    12             default:
    13                 break;
    14             }
    15         }
    16     };
    17     ……
    18 
    19     @Override
    20     public void onClick(View v) {
    21         switch (v.getId()) {
    22         case R.id.change_text:
    23             new Thread(new Runnable() {
    24                 @Override
    25                 public void run() {
    26                     Message message = new Message();
    27                     message.what = UPDATE_TEXT;
    28                     handler.sendMessage(message); // 将Message 对象发送出去
    29                 }
    30             }).start();
    31             break;
    32         default:
    33             break;
    34         }
    35     }
    36 }

    这里我们先是定义了一个整型常量 UPDATE_TEXT,用于表示更新 TextView这个动作。然后新增一个 Handler 对象,并重写父类的 handleMessage 方法,在这里对具体的 Message进行处理。如果发现 Message 的 what 字段的值等于 UPDATE_TEXT,就将 TextView显示的内容改成 Nice to meet you。下面再来看一下hange Text 按钮的点击事件中的代码。可以看到,这次我们并没有在子线程里直接进行 UI 操作,而是创建了一个 Message(android.os.Message)对象,并将它的 what 字段的值指定为 UPDATE_TEXT,然后调用 Handler 的 sendMessage()方法将这条Message 发送出去。很快,Handler 就会收到这条 Message,并在 handleMessage()方法中对它进行处理。注意此时 handleMessage()方法中的代码就是在主线程当中运行的了,所以我们可以放心地在这里进行 UI 操作。接下来对 Message 携带的 what 字段的值进行判断,如果等于UPDATE_TEXT,就将 TextView显示的内容改成 Nice to meet you。现在重新运行程序,可以看到屏幕的正中央显示着 Hello world。然后点击一下 ChangeText按钮,显示的内容着就被替换成 Nice to meet you,如图:

      使用Massage消息机制处理ui线程,简单操作。接下来解析异步消息处理机制的到底是如何工作的。

      Android 中的异步消息处理主要由四个部分组成,Message、Handler、MessageQueue和Looper。其中Message和Handler在上一小节中我们已经接触过了,而MessageQueue和Looper对于你来说还是全新的概念,下面我就对这四个部分进行一下简要的介绍。

      1. MessageMessage 是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。上一小节中我们使用到了 Message 的 what 字段,除此之外还可以使用 arg1 和 arg2 字段来携带一些整型数据,使用 obj字段携带一个 Object 对象。

      2. HandlerHandler 顾名思义也就是处理者的意思,它主要是用于发送和处理消息的。发送消息一般是使用 Handler的SendMessage()方法,而发出的消息经过一系列地辗转处理后,最终会传递到 Handler的 handleMessage()方法中。

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

      4. LooperLooper是每个线程中的 MessageQueue的管家,调用 Looper的 loop()方法后,就会进入到一个无限循环当中,然后每当发现 MessageQueue 中存在一条消息,就会将它取出,并传递到 Handler 的 handleMessage()方法中。每个线程中也只会有一个 Looper对象。

      了解了 Message、Handler、MessageQueue 以及 Looper的基本概念后,我们再来对异步消息处理的整个流程梳理一遍。首先需要在主线程当中创建一个 Handler 对象,并重写handleMessage()方法。然后当子线程中需要进行 UI 操作时,就创建一个 Message 对象,并通过 Handler 将这条消息发送出去。之后这条消息会被添加到 MessageQueue 的队列中等待被处理,而 Looper 则会一直尝试从 MessageQueue 中取出待处理消息,最后分发回 Handler的 handleMessage()方法中。由于 Handler是在主线程中创建的,所以此时 HandleMessage()方法中的代码也会在主线程中运行,于是我们在这里就可以安心地进行 UI 操作了。整个异步消息处理机制的流程示意图:

      一条 Message 经过这样一个流程的辗转调用后,也就从子线程进入到了主线程,从不能更新 UI 变成了可以更新 UI,整个异步消息处理的核心思想也就是如此。

      下面分享自己的所学所做关于安卓中的一些消息处理,信息的传递。bundle传递object对象。

  • 相关阅读:
    MPI 学习
    关于谱聚类
    线程调度的学习例子
    [转] Linux的IO复用
    网络编程socket
    关于python机器学习常用算法的例子
    [转](阿里笔试)使用多线程和sleep函数生成字符串的伪随机排列
    Single Number II
    阿里面试题,N个士兵的通话问题
    凸优化算法之牛顿法
  • 原文地址:https://www.cnblogs.com/nSai-sj/p/6290489.html
Copyright © 2020-2023  润新知