Handler和异步消息处理机制的解析!!

来源:互联网 发布:centos grub win7 编辑:程序博客网 时间:2024/04/29 23:40
1.Handler的基本概念
在Android的开发当中有很多功能都是不能放在Activity的正常的操作当中,比如onCreate(),和onStart()方法里面,因为这样来说,比较费时,比如下载一个东西,如果放在主线程当中,那么可能这个下载的时间中整个Activity是处于无响应的状态的,如果长时间的下载不下来,那么Activity会报错。
 Android程序启动以后会启动一个进程,所有的组件都在这个进程里面运行。开始这个进程只包含一个线程,叫做UI主线程,负责处理UI界面的更新以及显示,但是对于那些费事的操作(超过5S会卡顿)需要单独启动一个子线程去处理。子线程处理完毕后会将结果通知给UI主线程,主线程得到结果后更新UI界面。在AndroidUI开发中,我们经常会使用Handler来控制主UI程序的界面变化。有关Handler的作用,我们总结为:与其他线程协同工作,接收其他线程的消息并通过接收到的消息更新主UI线程的内容。 我们假设在一个UI界面上面,有一个按钮,当点击这个按钮的时候,会进行网络连接,并把网络上的一个字符串拿下来显示到界面上的一个 TextView上面,这时就出现了一个问题,如果这个网络连接的延迟过大,可能是10秒钟甚至更长,那我们的界面将处于一直假死状态,而如果这段时间超 5秒钟的话,程序会出现异常。这时我们会想到使用线程来完成以上工作,即当按钮被按下的时候新开启一个线程来完成网络连接工作,并把得到的结果更新到UI上面。但是,这时候又会 出现另一个问题,在Android中,主线程是非线程安全的,也就是说UI的更新只能在本线程中完成,其他线程无法直接对主线程进行操作。为了解决以上问题,Android设计了Handler机制,由Handler来负责与子线程进行通讯,从而让子线程与主线程之间建立起协作的桥梁,使AndroidUI更新的问题得到完美的解决。
2.Handler基本使用方法
什么是线程队列呢?
是一种数据结构,先进先出的数据结构

3.使用Handler更新ProgressBar

Handler(2):
1.Handler与线程
Handler中对线程的处理并不是真正的启动了另外一个线程,而是直接的在原有的线程上调用run()方法。
输出的结果:

可以看出是一模一样的结果。????问题?为什么要这么用
那么对于Thread呢?

可以看出不一样.我们用标准的Java原理,用Thread来实现,然后start().
2.Bundle的用法
什么是Bundle?以String为键,其他数据类型为值的一个Mapping,相当于把数据打成一个包。可以当作数据存储的一个工具,我们可以把我们需要的数据(键值对)给存储Bundle里面,然后用的时候在把它取出来。
对于启动一个线程,我们需要Looper这个对象,那什么是Looper呢?首先它是一个类,由Android框架提供的。
干嘛用呢?Looper这个东西呢,可以循环的从队列中取得消息
3.在新线程当中处理消息的方法


4.通过子线程更新UI的一个操作:
首先我们需要新建一个thridactivity_main.xml这个布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="changeText"
android:text="ChangeText"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/tv"
android:gravity="center"/>

</LinearLayout>
接着,我们新建一个ThridActivity.java这个类,然后继承Activity,代码如下:
package songzhixiang.android.com.handler03;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;

/**
* Created by Song on 2016/5/26.
* 通过子线程更新UITextView
*/
public class ThridActivity extends Activity {
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.thridactivity_main);
tv = (TextView) findViewById(R.id.tv);
}
//点击事件
public void changeText(View view)
{
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.obj = "hello";
handler.sendMessage(message);
}
}).start();
}
public Handler handler =new Handler()
{
@Override
public void handleMessage(Message msg) {
String s = (String) msg.obj;
tv.setText(s);
}
};
}
然后我们就可以进行线程来进行UI的更新了。

5.解析异步消息处理机制
Android中,异步消息有四个部分:
  1. Message
  2. Handler
  3. MessageQueue
  4. Looper
那么对于Message是什么呢?Message就是线程之间传递的消息,用于在不同线程之间交换数据。
Handler呢?上面已经介绍的很清楚了,注意的就是发送消息一般是使用Handler的sendMessage()方法,然后最后会传递到Handler的handlemessage()方法中。
MessageQueue呢?消息队列,存放所有通过Handler发送的消息,这些消息会一直存放在消息队列中,等待被处理。注意,每个线程中只有一个消息队列对象。
Looper呢?相当于消息队列的管家,负责从消息队列中循环取出数据,每个线程中也只有一个Looper对象。

总结:
异步消息的处理就是,首先在主线程中新建一个Handler对象,并且在里面写入handlerMessage方法,这里面才是更新UI哦。然后new Thread(new Runnable{}).start();这个方法,在里面的run()方法里面新建一个Message对象,并且通过Handler将这条消息发送出去,也就是sendMessage方法。之后呢,这条消息就会被添加到消息队列中(MessageQueue)等待被处理,这时候管家来了(Looper)来从里面循环取出消息,发到Handler的handlerMessage()方法中,然后之后进行逻辑代码,也就是你要更新UI的操作了,比如进行文字的改变,解析JSON数据到UI等等。


0 0
原创粉丝点击