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中也没有发现任何内存泄露等不好的东西。
  • 相关阅读:
    状态保持 session和cookie
    情人节——爱心代码
    Python常见的内置函数
    django
    面向对象和面向过程
    字符串的常见操作
    常见的数据类型
    Flask
    阿里云Centos7.6中部署nginx1.16+uwsgi2.0.18+Django2.0.4
    python中json和dict的基本区别
  • 原文地址:https://www.cnblogs.com/Codenewbie/p/2986717.html
Copyright © 2011-2022 走看看