安卓UI线程与异步消息处理机制

1,事实上安卓的UI线程是不安全的,所以如果想要更新应用程序的UI元素,必须在主线程中更新

先看一个例子

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.androidthreadtest.MainActivity" >

    <Button
        android:id="@+id/change_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Change Text" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Hello world"
        android:textSize="20sp" />

</RelativeLayout>

界面布局图

我们想要的效果是点击上面的按钮,然后改变下面的文本操作

所以假定我们有如下的代码

public class MainActivity extends Activity implements OnClickListener {
	private static final int UPDATE_TEXT=1;
private TextView text;
private Button changeText;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		text = (TextView) findViewById(R.id.text);
		changeText = (Button) findViewById(R.id.change_text);
		changeText.setOnClickListener(this);
	}
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.change_text:
			new Thread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
			    text.setText("内容都已经改变咯");
				}
			}).start();
			break;

		default:
			break;
		}
	}
}

想改变界面的中间的内容,但是发现会出现错误

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

子线程中更新出现的错误

安卓不允许在子线程中进行UI操作

2,所以解决上面UI子线程问题的办法就是异步消息处理机制

安卓中的异步消息处理主要由四个部分组成:Message,Handler,MessageQueue和Looper.

1,Message

Message是在线程间进行传递消息的。

定义一个包含描述性和任意数据对象的消息是可以被传给Handler的。

大致有Int类型的what agr1 arg2字段和一个Object对象的obj字段

2,Handler

Handler就是处理者的意思。主要用于发送和处理消息

发送消息一般是用到方法sendMessage(),而发出的消息进过一些列的辗转处理最终会传递到Handler的handleMessage()方法中

3,MessageQueue

MessageQueue是消息队列,主要是用于存放所有通过handler发送的消息,这部分消息会一直存在消息队列中等待被处理。

每个线程中只会有一个MessageQueue对象

4,Looper

Looper是每个线程中的MessageQueue的管家,调用Looper的loop()方法后就会进入到一个无限循环中

每当大仙MessageQueue中有消息,就会将其取出,然后传递到Handler的handlerMessage()方法中。

每个线程也只会有一个Looper对象

则异步消息的处理流程:

首先一般主线程中创建一个Handler对象,同时重写handleMessage()方法

当子线程需要进行UI操作的时候,就会创建一个Message对象,并通过Hnadler将这条消息发送出去

之后消息会被添加到MessageQueue队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理的消息,最后分发回Handler的handlerMessage()方法中

由于Handler是在主线程中创建的,所以此时handleMessage

()方法中的代码也会在主线程中运行,于是就可以正常的进行UI操作了

所以改进后的代码如下:

public class MainActivity extends Activity implements OnClickListener {
	private static final int UPDATE_TEXT=1;
private TextView text;
private Button changeText; 

private Handler handler=new Handler(){
	public void handleMessage(Message msg){
		switch (msg.what) {
		case UPDATE_TEXT:
			//在此处进行UI操作
			text.setText("内容在这里进行改变");
			break;
		default:
			break;
		}
	}
};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		text = (TextView) findViewById(R.id.text);
		changeText = (Button) findViewById(R.id.change_text);
		changeText.setOnClickListener(this);
	}
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.change_text:
			new Thread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
			//不能在这里直接改变
			/*	text.setText("内容都已经改变咯");	*/
					Message message=new Message();
					message.what=UPDATE_TEXT;
					//将message对象发送出去
					handler.sendMessage(message);
				}
			}).start();
			break;

		default:
			break;
		}
	}
}

点击后会出现想要的结果

时间: 2024-10-12 12:27:19

安卓UI线程与异步消息处理机制的相关文章

Android线程之异步消息处理机制(二)——Message、Handler、MessageQueue和Looper

异步消息处理机制解析 Android中的异步消息处理主要有四个部分组成,Message.Handler.MessageQueue和Looper. 1.Message Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据.上个例子中就使用了Message的what字段,除此之外还可以使用arg1和arg2字段来携带一些整形数据,使用obj字段携带一个Object对象. 2.Handler Handler顾名思义也就是处理者的意思,它主要是用于发送和处理消息的

Android线程之异步消息处理机制(一)

Android不允许在子线程中进行UI操作,但是有些时候,我们必须在子线程里去执行一些耗时任务,然后根据任务的执行结果来更新相应的UI控件.对于这种情况,Android提供了一套异步消息处理机制,完美地解决了在子线程中进行UI操作的问题. 主线程: 1.新建Handler对象 2.重写父类handleMessage方法,在这里进行UI操作,此方法的代码在主线程中. 子线程: 1.创建Message对象 2.指定Message的what字段 3.调用handler的sendMessage方法,把m

Android Learning:多线程与异步消息处理机制

在最近学习Android项目源码的过程中,遇到了很多多线程以及异步消息处理的机制.由于之前对这块的知识只是浅尝辄止,并没有系统的理解.但是工程中反复出现让我意识到这个知识的重要性.所以我整理出这篇博客,主要介绍了线程和异步处理机制的意义和用法,目的在于帮助初学者能够加深对异步消息处理机制的理解,在实际Android工程中能够更多地使用AsyncTask工具类在子线程中进行UI更新. 一.Android当中的多线程[1] 在Android当中,当一个应用程序的组件启动的时候,并且没有其他的应用程序

解析异步消息处理机制

一.概述       Android异步消息处理机制主要由四个部分组成,Message.Handle.MessageQueue和Looper.下面我就对这四个部分进行一下简要的介绍. 1.Message      Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据. 2.MessageQueue      MessageQueue 是消息队列,它主要用于存放所有由 Handler 发送过来的消息,这部分消息会一直在消息队列中,等待被处理.每个线程中只会有

Android异步消息处理机制(3)asyncTask基本使用

本文翻译自android官方文档,结合自己测试,整理如下. 概述 AsyncTask抽象类,翻译过来就是异步任务,能够合理并方便的使用UI线程.该类可以实现将后台操作结果显示在UI线程中,而不需要我们自己实现子线程或者handler(当然它内部也是借助这两者实现的). 虽然AsyncTask可以提供后台运行并将结果显示在UI上,但是理想情况应该是后台操作最多只能是几秒钟,若要执行长时间的操作强烈建议使用java中的Executor,ThreadPoolExecutor,FutureTask等.

Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 很多人面试肯定都被问到过,请问Android中的Looper , Handler , Message有什么关系?本篇博客目的首先为大家从源码角度介绍3者关系,然后给出一个容易记忆的结论. 1. 概述 Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念.那么什么叫异步消息处理线程呢?异步

Android多线程——异步消息处理机制

Android中的异步消息处理机制主要由四个部分组成,Message.Handler.MessageQueueh和Looper.这里先简要介绍一下四个部分. 1.Message Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据,Message可以使用what.arg1和arg2字段来携带一些整形数据.使用obj来携带一个Object对象. 2.Handler Handler是处理者的意思,主要用于发送和处理消息.发送消息一般是使用Handler的sen

Android 异步消息处理机制

转载自博客:http://blog.csdn.net/lmj623565791/article/details/38377229/ 1. 概述 Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念.那么什么叫异步消息处理线程呢?异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次,从其内部的消息队列中取出一个消息,然后回调相应的消息处理函数,执行完成一个消息后则继续循环.若消息队列为空,线程则会阻塞等待. 说了这一堆,那么和Handler

[学习总结]6、Android异步消息处理机制完全解析,带你从源码的角度彻底理解

开始进入正题,我们都知道,Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃.相信大家在日常的工作当中都会经常遇到这个问题,解决的方案应该也是早已烂熟于心,即创建一个Message对象,然后借助Handler发送出去,之后在Handler的handleMessage()方法中获得刚才发送的Message对象,然后在这里进行UI操作就不会再出现崩溃了. 这种处理方式被称为异步消息处理线程,虽然我相信大家都会用,可是你知道它背后的原理是什么样的吗?今天我们就来一起