Android中的好多应用,如UI更新,游戏开发,和耗时的操作都需要用到多线程的知识。而对Android中的线程机制好多人多觉得学习有困难。下面我们就一起来学习一下。

谈及Android中的线程我们会涉及到如下几个概念:

1. Handler 2. Looper 3. HandlerThread 4.Message 5. MessageQueue

下面我们由浅入深来探讨一下。我们用java多线程中很经典的例子计时器为例。我们要编写实现一个计时器,该如何编写呢?按照java中多线程的思路,我们很自然的会这样实现

代码如下:

package xuan.blog.hander;    import android.app.Activity;  import android.os.Bundle;  import android.util.Log;  import android.view.View;  import android.widget.Button;  import android.widget.TextView;    public class clockActivity extends Activity {      /** Called when the activity is first created. */      private String TAG="clockActivity";      private Button endButton;      private TextView textView;      private Thread clockThread;      private int timer=0;      private boolean isRunning=true;      @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.main);          endButton=(Button)findViewById(R.id.endBtn);          textView=(TextView)findViewById(R.id.textview);          endButton.setOnClickListener(new View.OnClickListener() {                            @Override              public void onClick(View v) {                  // TODO Auto-generated method stub                  isRunning=false;              }          });          clockThread=new Thread(new Runnable(){                @Override              public void run() {                  // TODO Auto-generated method stub                  while(isRunning){                      try{                          Thread.currentThread().sleep(1000);                          timer++;                          textView.setText("走了"+timer+"秒");                          Log.d(TAG,"time:"+timer);                      }catch(InterruptedException e){                          e.printStackTrace();                      }                  }              }});          clockThread.start();      }  }  

我们用Thread的构造方法创建了一个线程对象,并启动了该线程,在该线程中来计算并更新textView。

然而,在Android中运行我们会发现这样会抛出异常!!

这是因为Android系统中的视图组件并不是线程安全的,在Android中UI的更新必须由主线程来完成。而上面我们违反了这一规则。

我们应该如何解决这个问题呢?我们应该让主线程负责创建,显示和更新UI控件,启动子线程,停止子线程。让子线程完成计算并向主线程发出更新UI的消息让主线程来更新UI。

如何实现子线程和主线程之间的消息传递呢?Android中为我们提供了Handler机制。

Handler是android中多线程间传递消息和计划任务的“工具”类。Handler会在多个线程中发送Message和Runnable。

andler在多线程中有两方面的应用:

1.发送消息,在不同的线程间发送消息,使用方法sendXXX();

2.计算任务,在未来执行某任务,使用方法postXXX();

一个线程发出消息后,接受消息是通过重写Handler类中的handleMessage(Message)方法实现。

Handler也可以通过postXXX()方法提交计划任务,当取出一个任务Runnable是便会执行其中的run()方法。

经过分析,我们用handler发送消息的应用修改上述代码:

public class clockActivity extends Activity {      /** Called when the activity is first created. */      private String TAG="clockActivity";      private Button endButton;      private TextView textView;      private Thread clockThread;      private int timer=0;      private boolean isRunning=true;      private Handler handler;      @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.main);          endButton=(Button)findViewById(R.id.endBtn);          textView=(TextView)findViewById(R.id.textview);          endButton.setOnClickListener(new View.OnClickListener() {                            @Override              public void onClick(View v) {                  // TODO Auto-generated method stub                  isRunning=false;              }          });          handler=new Handler(){                @Override              public void handleMessage(Message msg) {                  // TODO Auto-generated method stub                  super.handleMessage(msg);                  switch(msg.what){                  case 0:textView.setText("走了"+timer+"秒");                  }              }                        };          clockThread=new Thread(new Runnable(){                @Override              public void run() {                  // TODO Auto-generated method stub                  while(isRunning){                      try{                          Thread.currentThread().sleep(1000);                          timer++;                          //textView.setText("走了"+timer+"秒");                          Message msg=new Message();                          msg.obj=timer;                          msg.what=0;                          handler.sendMessage(msg);                          Log.d(TAG,"time:"+timer);                      }catch(InterruptedException e){                          e.printStackTrace();                      }                  }              }});          clockThread.start();      }  }  

通过这种方式便实现了子线程和主线程之间的通信。当然我们也可以通过Handler的执行计划任务来完成这计时器的功能,代码如下:

public class clockActivity extends Activity {      /** Called when the activity is first created. */      private String TAG="clockActivity";      private Button endButton;      private TextView textView;      private int timer=0;      private boolean isRunning=true;      private Handler handler;      @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.main);          endButton=(Button)findViewById(R.id.endBtn);          textView=(TextView)findViewById(R.id.textview);          endButton.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  // TODO Auto-generated method stub                  isRunning=false;              }          });          handler=new Handler();          Runnable r=new Runnable(){                @Override              public void run() {                  // TODO Auto-generated method stub                  if(isRunning){                      textView.setText("走了"+timer+"秒");                      timer++;                      handler.postDelayed(this, 1000);//提交任务r,延时1秒执行                  }              }          };          handler.postDelayed(r, 1000);          }  }  

注意运行完handler.postDelayed(r,1000);只是提交了一次任务,因此为了反复执行要在run()方法中再次提交。注意上述方法中发送任务和执行任务都是在主线程中实现的,我们并没有令启动线程。

在下一篇文章中,我们在具体分析一下Android中的消息机制。

更多相关文章

  1. Android消息通信之无所不能的第三方开源项目EventBus
  2. Android应用程序键盘(Keyboard)消息处理机制分析
  3. Android应用程序启动Binder线程源码分析
  4. Android消息推送实现
  5. Android的消息机制(Handler的工作原理)
  6. Android应用程序键盘(Keyboard)消息处理机制分析(1)
  7. Android - Android 的消息机制
  8. Android之进程与线程

随机推荐

  1. Android解析XML
  2. 关于android创建对话框报错The method se
  3. Android(安卓)LinearLayout遇到的坑
  4. android 获取应用列表 点击打开应用
  5. Android(安卓)adb获取屏幕分辨率
  6. Android(安卓)SDK的更新相关
  7. android 之 @ 与? 的区别
  8. Android(安卓)Activity界面切换添加动画
  9. TextView显示链接
  10. Android与webview JS 键值编码差异