辛辛苦苦写的程序,在安卓4.0上运行不了,苦了我了。查了半天发现是4.0的主线程上不能执行联网操作,只得单启线程运行。同时线程内不得更新UI,handler监听改UI。
一、线程的应用
简单的启线程
new Thread(new Runnable() { public void run() { //要执行的代码 } }).start();
带Handler.sendEmptyMessage修改UI的线程
// 定义Handler对象 final Handler handler = new Handler() { @Override // 当有消息发送出来的时候就执行Handler的这个方法 public void handleMessage(Message msg) { super.handleMessage(msg); // 处理UI switch(msg.what){ case 0: //要处理的事情 break; } } }; new Thread() { @Override public void run() { // 你要执行的方法 // 执行完毕后给handler发送一个空消息 handler.sendEmptyMessage(0); } }.start();
带Handler.post的修改UI的线程
new Thread(new Runnable() { @Override public void run() { //要执行的内容 handler.post(new Runnable() { public void run() { //要执行更新界面的内容 } }); } }).start();
二、post和sendMessage
先看一下Message类中定义一个私有的变量:Runnable callback;
再来看一下handler.post(Runnable callback)方法的源码:
public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }
再看一下sendMessageDelayed的源码:
public final boolean sendMessageDelayed(Message msg, long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); }
这里面有个关键就是方法getPostMessage(r)这个方法,他将Runnable转成一个Message,他内部到底干了什么呢?看一下他的源码:
private final Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
这里面就是将Runnable转化成一个Message,其他看他的代码很简单,就是先获取一个空消息Message.obtain(),然后将Message中的callback的值设置成Runnable,这时候就了解到了Message中的callback的作用了!
同时也了解一下View.post(Runnable r)方法的作用:看一下实例代码:
final Button btn = (Button)findViewById(R.id.btn); btn.post(new Runnable(){ @Override public void run() { btn.setText("不是好人"); } }); }
上面的代码就是更新btn中的内容,同样下面的代码也可以达到这种效果:
Handler handler = new Handler(); final Button btn = (Button)findViewById(R.id.btn); handler.post(new Runnable(){ @Override public void run() { btn.setText("不是好人"); } }); }
不同是这个是用handler.post方法,一个是用View.post方法,现在来看一下View.post方法的源代码:
public boolean post(Runnable action) { Handler handler; AttachInfo attachInfo = mAttachInfo; if (attachInfo != null) { handler = attachInfo.mHandler; } else { // Assume that post will succeed later ViewRootImpl.getRunQueue().post(action); return true; } return handler.post(action); }
方法中主要的功能代码就是attachInfo.mHandler,获取当前线程的hanlder,和我们在一个线程中定义一个Handler的效果是一样的。
Forsett worked out for the Lions on Monday.
Android 线程菜鸟应用,浅析post和sendMessage – 爱上极客 what can i do
Android 线程菜鸟应用,浅析post和sendMessage – 爱上极客 i miss you