[Android]Thread线程入门2

现在我们来做一个简单的例子。如下图:

[Android]Thread线程入门2
屏幕上有两个按钮和1个数字。点击start thread按钮,开始线程。这个线程每隔1秒,数字加1.屏幕上的数字不停变换。
[Android]Thread线程入门2
点击stop thread,线程停止,数字不再加1.
 
layout文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical" >    
   <Button android:id="@+id/btnStart"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Start Thread" />
   <Button android:id="@+id/btnStop"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Stop Thread" />
   <TextView
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:textSize="30dip"
       android:textColor="#ffff0000"
       android:text="0"
       android:layout_marginLeft="30dip"
       android:id="@+id/txtShow" />
   
</LinearLayout>
我们来看看源代码:
public class TestThreadActivity extends Activity {
   //声明变量
   private Handler mHandler = null;
   private MyThread mThread = null;
   
   private TextView mTextView;
   private Button mButtonStart;
   private Button mButtonStop;
   //用来计数的变量
   private int mSecond = 0;
   //用来设置线程是否停止
   private boolean mStop = false;
   
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       //赋值
       mThread = new MyThread();
       mHandler = new MyHandler();
       
       mTextView = (TextView)findViewById(R.id.txtShow);
       mButtonStart = (Button)findViewById(R.id.btnStart);
       mButtonStop = (Button)findViewById(R.id.btnStop);
       
       mButtonStart.setOnClickListener(new View.OnClickListener() {
           
           public void onClick(View v) {
               //启动线程
               startThread();
           }
       });
       
       mButtonStop.setOnClickListener(new View.OnClickListener() {
           
           public void onClick(View v) {
               //停止线程
               stopThread();
           }
       });
   }
   //启动线程
   private void startThread()
   {
       mStop = false;
       mThread.start();
   }
   //停止线程
   private void stopThread()
   {
       mStop = true;
   }
   
   //自定义Handler,用来显示屏幕上的数字
   private class MyHandler extends Handler
   {
       @Override
       public void handleMessage(Message msg)
       {
           switch(msg.what)
           {
               case 1:
               {
                   mSecond ++; //second increase
                   //改变UI
                   mTextView.setText(Integer.toString(mSecond));
                   break;
               }
           }
       }
   }
   //自定义线程,通过Message传递消息给Handler,让Handler改变UI显示
   private class MyThread extends Thread
   {
       @Override
       public void run()
       {
           while(!mStop)
           {
               try
               {
                   Thread.sleep(1000);
               }
               catch(InterruptedException e)
               {
                   e.printStackTrace();
               }
               //do something
               Message msg = new Message();
               msg.what = 1;                
               //send message
               mHandler.sendMessage(msg);
           }
       }
   }  
 
   
}
这样这个例子就完成了。
但这例子有bug。如果点了停止按钮后,我们再点Start Thread按钮,就有问题了。Exception如下:
[Android]Thread线程入门2
主要信息是Thread already started.那么我们修改一下代码:
private void startThread()
{
   //将标志位设为false,表示线程开始运行
   mStop = false;        
   //如果线程还没有开始过,就调用start。如果已经开始了,用start就会出错了
   if(mThread.getState() == Thread.State.NEW)
       mThread.start();
}

在自定义的MyThread增加对停止线程的处理,如下:

private class MyThread extends Thread
{
   @Override
   public void run()
   {
       while(!mStop)
       {    
           try
           {    
               Thread.sleep(1000);
           }
           catch(InterruptedException e)
           {    
               e.printStackTrace();
           }                
           
           Message msg = new Message();
           msg.what = 1;
           //send message
           mHandler.sendMessage(msg);
       }
       //在这里增加对停止线程的处理。停止线程用interrupt
       if(mStop)
           this.interrupt();
   }
}

这时候,点击start thread按钮,开始运行线程。屏幕上开始计数。点击stop thread,停止线程。屏幕上的数字维持不变。这时候再次点击start thread,不会出现异常。点击stop thread,也不会出现异常。这时候又有新问题了。屏幕上的数字就不会再变化了。

我们可不可以在点击start thread按钮的时候,让它继续计数呢?如何实现呢?
private void startThread()
{
   //设置标志位为false,表示运行线程
   mStop = false;
   //如果线程从来没有开始过,运行start
   if(mThread.getState() == Thread.State.NEW)
   {
       mThread.start();
   }
   else if(mThread.getState() == Thread.State.TERMINATED)
   {
       //如果线程已经被interrupt了,那么它的状态就是terminated。即这个线程完整的结束了。
       //这时候就重新new一个线程,再start
       try
       {
           mThread = new MyThread();
           mThread.start();
       }
       catch(Exception e)
       {
           
       }
   }
   
}
这时候再次点击start thread,屏幕上从当前数字开始继续计数。直到按下stop thread为止。
既然如此,不如精简下代码,每次按下start thread,我都new thread,看看效果:
private void startThread()
{
   mStop = false;
   mThread = new MyThread();
   mThread.start();
}
显示效果和上面一样。而且从logcat中也没有发现任何内存泄露等不好的东西。
posted @ 2013-03-28 14:45  Myna Wang  阅读(365)  评论(0编辑  收藏  举报
免费流量统计