首页 > 代码库 > 第四章 Android开发三大基石—Activity、Service和Handler(6)
第四章 Android开发三大基石—Activity、Service和Handler(6)
4.3 Android线程间的通信—消息机制
在Android程序运行中,线程之间或者线程内部进行信息交互时经常会使用到消息,如果我们熟悉这些基础的东西及其内部原理,将会使我们的Android开发变的更加容易,从而更好地架构系统。下面,就让我们来看看Android中的消息机制到底是怎样一回事吧。
4.3.1消息的传递—Handler的使用
在Android中,线程之间进行信息交互时经常会使用消息,那么,“消息”是在什么时候使用呢?它的工作原理又是怎么样的呢?
在解释这些之前,我们先来看下面这个Activity:
// import略 public class MainActivity extends Activity implements View.OnClickListener {
private TextView stateText; private Button btn;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.message); stateText = (TextView) findViewById(R.id.my_text); btn = (Button) findViewById(R.id.my_btn); btn.setOnClickListener(this); } @Override public void onClick(View v) { new WorkThread().start(); } // 工作线程 private class WorkThread extends Thread { @Override public void run() { // 这里处理比较耗时的操作 // 处理完成后改变状态 stateText.setText("completed"); } } } |
在上面这个Activity中,咋一看,挺正常的,一个TextView,一个Button。但是运行后点击按钮马上就会报错:
ERROR/AndroidRuntime(3658): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views |
到底是怎么回事呢?原因在于,Android系统中的视图组件并不是线程安全的,如果要更新视图,必须在主线程中更新,不可以在子线程中执行更新的操作。
既然这样,我们就在子线程中通知主线程,让主线程做更新操作吧。那么,我们如何通知主线程呢?我们需要使用到Handler对象。
我们稍微修改一下上面的代码:
// import略 public class MainActivity extends Activity implements View.OnClickListener {
private TextView stateText; private Button btn;
private static final int COMPLETED = 1;
private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == COMPLETED) { stateText.setText("completed"); } } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.message); stateText = (TextView) findViewById(R.id.my_text); btn = (Button) findViewById(R.id.my_btn); btn.setOnClickListener(this); } @Override public void onClick(View v) { new WorkThread().start(); } // 工作线程 private class WorkThread extends Thread { @Override public void run() { // 这里处理比较耗时的操作 Message msg = new Message(); msg.what = COMPLETED; handler.sendMessage(msg); } } } |
通过上面这种方式,我们就可以解决线程安全的问题,把复杂的任务处理工作交给子线程去完成,然后子线程通过Handler对象告知主线程,由主线程更新视图,这个过程中消息机制起着重要的作用。
第四章 Android开发三大基石—Activity、Service和Handler(6)