zoukankan      html  css  js  c++  java
  • [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中也没有发现任何内存泄露等不好的东西。
  • 相关阅读:
    Atitit.随时间变色特效 ---包厢管理系统的规划
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit.执行cli cmd的原理与调试
  • 原文地址:https://www.cnblogs.com/Codenewbie/p/2986717.html
Copyright © 2011-2022 走看看