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. 比較具体的handle机制
  2. Android中的消息机制:Handler消息传递机制
  3. Android(安卓)Handler机制剖析
  4. Android应用程序启动Binder线程源码分析
  5. 如果让我重新设计一款Android(安卓)App
  6. Android的消息机制(Handler的工作原理)
  7. Android(安卓)为什么使用DVM虚拟机,而不使用Java JVM??
  8. Android的内存机制
  9. 浅析Android线程模型一 --- 转

随机推荐

  1. Android小笔记之存储与读取
  2. Android 自定义ImageView,支持圆角和直角
  3. 1、android 模拟小球来回撞墙效果(游戏的
  4. android 返回键 事件
  5. android打电话、发短信实现
  6. Vibrator
  7. Android在线资源API
  8. Android Activity设置无标题和全屏
  9. Android HAL 研究开发 FOR LED
  10. Android 热更新ICON图标