这是一个每过三秒 定时弹出一个Toast的小demo
Android的线程分两类
一个是不带消息的普通线程
另一个则是带消息的消息线程
先来逐步分析
首先分析消息处理器Handler
用一个匿名内部类 重写handleMessage方法 传入msg
按套路 就是在方法中使用switch 来判断收到的不同的msg 来处理不同的业务逻辑
然后通过bundle 来接受数据 并且出一Toast
下面则是在发送bundle data->bundle->msg->handle
逻辑则是:
通过bundle发送消息到有消息的线程 通过handle来接受并且处理
不过这个有消息的线程很特殊 (消息线程的队列FIFO模型)为了不影响主线程(因为主线程主要是负责UI 人机交互界面的) 所以另外创建了一个线程 在这个线程中合理使用handle
明白了bundle的作用 四份类似与intent 不过intent是只能在Activity之间互相的传送而bundle则更加方便。
同时消息处理的线程中 必须要有准备工作Looper.prepare();
同时线程的最后 要进行线程的循环Looper.loop();
消息线程千万不能出现子主线程中否则会出出现的线程不死的现象
并且
没有用该机制的后果
错误代码如下
new Thread()
{
@Override
public void run()
{
this.setName("Thread Dispatch");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 循环10次,显示10个Toast
for(int i=1;i<=10;i++)
{
final int k=i;
new Thread()
{
public void run()
{
this.setName("Toast Thread "+k);
Looper.prepare();
//显示Toast
Toast.makeText
(
LooperThreadExampleActivity.this,
"Toast 消息"+k,
Toast.LENGTH_SHORT
).show();
Looper.loop();
}
}.start();
//休息3000ms再发下一条消息
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
在AS的线程监控下 线程不死
new Thread()
{
@Override
public void run()
{
this.setName("Thread Dispatch");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 循环10次,显示10个Toast
for(int i=1;i<=10;i++)
{
final int k=i;
new Thread()
{
public void run()
{
this.setName("Toast Thread "+k);
Looper.prepare();
//显示Toast
Toast.makeText
(
LooperThreadExampleActivity.this,
"Toast 消息"+k,
Toast.LENGTH_SHORT
).show();
Looper.loop();
}
}.start();
//休息3000ms再发下一条消息
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
====================================================================
源码如下
线程的代码
public class LooperThread extends Thread
{
//消息处理器
Handler hd;
//上下文
public Context context;
public LooperThread(Context context)
{
this.context=context;
}
@Override
public void run()
{
this.setName("Toast Thread 线程");
//进行prepare,建立消息队列
Looper.prepare();
//创建消息处理器对象
hd=new Handler()
{
@Override
public void handleMessage(Message msg)
{
//调用父类处理
super.handleMessage(msg);
//根据消息what编号的不同,执行不同的业务逻辑
switch(msg.what)
{
//将消息中的内容提取出来显示在Toast中
case Constant.DISPLAY_TOAST:
//获取消息中的数据
Bundle b=msg.getData();
//获取内容字符串
String msgStr=b.getString("msg");
//显示Toast
Toast.makeText
(
context,
msgStr,
Toast.LENGTH_SHORT
).show();
break;
}
}
};
//建立消息循环
Looper.loop();
}
}
============================================================================
Activity的代码
public class LooperThreadExampleActivity extends Activity
{
//有消息循环的线程
LooperThread lt;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//创建自定义的有消息循环的线程的对象
lt=new LooperThread(this);
//启动线程
lt.start();
//开启一个普通的线程,定时向消息循环线程发送消息
new Thread()
{
@Override
public void run()
{
//循环10次,发送10条消息,显示10个Toast
for(int i=1;i<=10;i++)
{
//创建内容字符串
String msgStr="计数器值:"+i;
//创建消息数据Bundle
Bundle b=new Bundle();
//将内容字符串放进数据Bundle中
b.putString("msg", msgStr);
//创建消息对象
Message msg=new Message();
//设置数据Bundle到消息中
msg.setData(b);
//设置消息的what值
msg.what=Constant.DISPLAY_TOAST;
//发送消息
lt.hd.sendMessage(msg);
//休息3000ms再发下一条消息
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}