前言:Android开发当中,绝大多数的UI操作都应该在主线程当中进行,主线程之外原则上不允许修改View(progressBar等特殊控件除外)。在一个应用程序当中,主线程通常用于接收用户的输入信息,以及将运算的结果反馈给用户,因此,对一些可能会产生阻塞的操作,必须放置在WorkerThread(子线程)中,但WorkerThread中的参数又不能反馈给主线程,因此就产生了一种通信方法:Handler!
一.1.Handler用来处理主线程与子线程之间的数据传输。
作用:把消息放到消息队列中。
2.Looper:消息队列循环器,不断的从消息队列中取出消息,取出的消息会再交给Handler来处理。如果消息队列没有消息,Looper会等待,该线程就会出现阻塞。
Java Code:
package com.gu.aatest;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button mButton;
private TextView mTextView;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.button);
mTextView = (TextView) findViewById(R.id.textview);
handler = new FirstHandler();
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// obtainMessage() 获取一个消息对象
Message msg = handler.obtainMessage();
// what为msg的属性
msg.what = 2;
/**
* 将消息放到消息队列中
*
* 步骤:1.Looper取出消息;2.Looper将会找到与消息对象对应的Handler对象;3.L
* ooper将会调用Handler的handleMessage()方法来处理信息对象
*/
handler.sendMessage(msg);
}
});
}
class FirstHandler extends Handler {
// 用来处理消息的handleMessage()方法
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
int what = msg.what;
System.out.println("what:" + what);
}
}
}
二.子线程向主线程发送消息
package com.gu.aatest;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button mButton;
private TextView mTextView;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.button);
mTextView = (TextView) findViewById(R.id.textview);
handler = new FirstHandler();
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// obtainMessage() 获取一个消息对象
Thread t = new NetWorkThread();
t.start();
}
});
}
class FirstHandler extends Handler {
// 用来处理消息的handleMessage()方法
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println("FirstHandler--当前线程为:"
+ Thread.currentThread().getName());
String s = (String) msg.obj;
mTextView.setText(s);
}
}
// 模拟从网络加载数据
class NetWorkThread extends Thread {
/**
* 重载方法
*/
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(2 * 1000);
System.out.println("NetWorkThread--当前线程为:"
+ Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String s = "从网络加载数据";
// 此处不能直接用TextView。setText(s)来显示,否则会报错
Message msg = handler.obtainMessage();
// sendMessage(msg)方法无论在主线程还是子线程都能发送
handler.sendMessage(msg);
}
}
}
打印结果如下,下面的main为主线程,其余为子线程
三.主线程向子线程发送消息
package com.gu.aatest;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button mButton;
private TextView mTextView;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.button);
mTextView = (TextView) findViewById(R.id.textview);
Thread thread = new NetWorkThread();
thread.start();
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// obtainMessage() 获取一个消息对象
Message msg = handler.obtainMessage();
handler.sendMessage(msg);
System.out.println("当前线程为:" + Thread.currentThread().getName());
}
});
}
// 模拟从网络加载数据
class NetWorkThread extends Thread {
/**
* 重载方法
*/
@Override
public void run() {
// TODO Auto-generated method stub
// 准备Looper
Looper.prepare();
handler = new Handler() {
/**
* 重载方法
*
* @param msg
*/
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println("NetWorkThread--当前线程为:"
+ Thread.currentThread().getName());
System.out.println("收到消息");
}
};
/**
* 调用Looper的Loop()方法后,Looper对象将不断的从消息队列中取出消息对象,
* 然后调用handler的handleMessage()方法处理消息对象,如果消息队列中没有了消息对象,则会线程阻塞
*/
Looper.loop();
}
}
}
输出结果如下;