Android中定时器Timer和TimerTask的启动,停止,暂停,继续等操作实例

时间:2021-09-07 00:08:51

下面是一个在Android中使用定时器Timer和TimerTask的启动,停止,暂停,继续等操作的demo。

需要注意的问题主要有两点:

1、Timer和TimerTask在调用cancel()取消后不能再执行 schedule语句,否则提示出错,提示如下:

[java] view plaincopyprint?
  1. D/AndroidRuntime( 6672): Shutting down VM  
  2. W/dalvikvm( 6672): threadid=1thread exiting with uncaught exception (group=0x40018560 
  3. E/AndroidRuntime( 6672): FATAL EXCEPTION: main  
  4. E/AndroidRuntime( 6672): java.lang.IllegalStateException: Timer was canceled  
  5. E/AndroidRuntime( 6672):    at java.util.Timer.scheduleImpl(Timer.java:563 
  6. E/AndroidRuntime( 6672):    at java.util.Timer.schedule(Timer.java:483 
  7. E/AndroidRuntime( 6672):    at com.snowdream.timerdemo.TimerDemoActivity$2.onClick(TimerDemoActivity.java:73 
  8. E/AndroidRuntime( 6672):    at android.view.View.performClick(View.java:2501 
  9. E/AndroidRuntime( 6672):    at android.view.View$PerformClick.run(View.java:9107 
  10. E/AndroidRuntime( 6672):    at android.os.Handler.handleCallback(Handler.java:587 
  11. E/AndroidRuntime( 6672):    at android.os.Handler.dispatchMessage(Handler.java:92 
  12. E/AndroidRuntime( 6672):    at android.os.Looper.loop(Looper.java:130 
  13. E/AndroidRuntime( 6672):    at android.app.ActivityThread.main(ActivityThread.java:3835 
  14. E/AndroidRuntime( 6672):    at java.lang.reflect.Method.invokeNative(Native Method)  
  15. E/AndroidRuntime( 6672):    at java.lang.reflect.Method.invoke(Method.java:507 
  16. E/AndroidRuntime( 6672):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841 
  17. E/AndroidRuntime( 6672):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599 
  18. E/AndroidRuntime( 6672):    at dalvik.system.NativeStart.main(Native Method)  
  19. W/ActivityManager(  154):   Force finishing activity com.snowdream.timerdemo/.TimerDemoActivity  
  20. W/ActivityManager(  154): Activity pause timeout for HistoryRecord{40550560 com.snowdream.timerdemo/.TimerDemoActivity}  
  21. W/ActivityManager(  154): Activity destroy timeout for HistoryRecord{40550560 com.snowdream.timerdemo/.TimerDemoActivity}  
  22. D/dalvikvm(  800): GC_EXPLICIT freed 13K, 58free 3127K/7431K, external 0K/0K, paused 70ms  
  23. D/dalvikvm(  562): GC_EXPLICIT freed 59K, 51free 2935K/5959K, external 245K/512K, paused 84ms  
  24. I/ActivityManager(  154): Start proc com.android.email for service com.android.email/.service.MailService: pid=6691 uid=10019 gids={30031015 

2、只能在UI主线程中更新控件/组件。在其他线程中,更新控件/组件,会提示出错,提示如下:

(注:这种情况下,可以通过Hander发送消息的方式来更新控件/组件,详情参考例子。)

[java] view plaincopyprint?
  1. E/AndroidRuntime( 6309): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created view hierarchy can touch its views.  
  2. E/AndroidRuntime( 6309):    at android.view.ViewRoot.checkThread(ViewRoot.java:2941 
  3. E/AndroidRuntime( 6309):    at android.view.ViewRoot.invalidateChild(ViewRoot.java:643 
  4. E/AndroidRuntime( 6309):    at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:669 
  5. E/AndroidRuntime( 6309):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511 
  6. E/AndroidRuntime( 6309):    at android.view.View.invalidate(View.java:5296 
  7. E/AndroidRuntime( 6309):    at android.widget.TextView.checkForRelayout(TextView.java:5533 
  8. E/AndroidRuntime( 6309):    at android.widget.TextView.setText(TextView.java:2730 
  9. E/AndroidRuntime( 6309):    at android.widget.TextView.setText(TextView.java:2598 
  10. E/AndroidRuntime( 6309):    at android.widget.TextView.setText(TextView.java:2573 
  11. E/AndroidRuntime( 6309):    at com.snowdream.timerdemo.TimerDemoActivity$1.run(TimerDemoActivity.java:48 
  12. E/AndroidRuntime( 6309):    at java.util.Timer$TimerImpl.run(Timer.java:284 


Demo源码如下:

TimerDemoActivity.java

[java] view plaincopyprint?
  1. package com.snowdream.timerdemo;  
  2.   
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. import android.app.Activity;  
  7. import android.os.Bundle;  
  8. import android.os.Handler;  
  9. import android.os.Message;  
  10. import android.util.Log;  
  11. import android.view.View;  
  12. import android.widget.Button;  
  13. import android.widget.TextView;  
  14.   
  15. public class TimerDemoActivity extends Activity  
  16.   
  17.     private static String  TAG "TimerDemo" 
  18.   
  19.     private TextView mTextView null 
  20.     private Button mButton_start null 
  21.     private Button mButton_pause null 
  22.   
  23.     private Timer mTimer null 
  24.     private TimerTask mTimerTask null 
  25.   
  26.     private Handler mHandler null 
  27.       
  28.     private static int count 0 
  29.     private boolean isPause false 
  30.     private boolean isStop true 
  31.   
  32.     private static int delay 1000 //1s   
  33.     private static int period 1000 //1s   
  34.   
  35.     private static final int UPDATE_TEXTVIEW 0 
  36.       
  37.     @Override  
  38.     public void onCreate(Bundle savedInstanceState)  
  39.         super.onCreate(savedInstanceState);  
  40.         setContentView(R.layout.main);  
  41.   
  42.         mTextView (TextView)findViewById(R.id.mytextview);   
  43.         mButton_start (Button)findViewById(R.id.mybutton_start);  
  44.         mButton_pause (Button)findViewById(R.id.mybutton_pause);  
  45.   
  46.   
  47.         mButton_start.setOnClickListener(new Button.OnClickListener()  
  48.             public void onClick(View v)  
  49.                 if (isStop)  
  50.                     Log.i(TAG, "Start");  
  51.                 else  
  52.                     Log.i(TAG, "Stop");  
  53.                  
  54.   
  55.                 isStop !isStop;  
  56.   
  57.                 if (!isStop)  
  58.                     startTimer();  
  59.                 }else  
  60.                     stopTimer();  
  61.                  
  62.   
  63.                 if (isStop)  
  64.                     mButton_start.setText(R.string.start);  
  65.                 else  
  66.                     mButton_start.setText(R.string.stop);  
  67.                  
  68.              
  69.         });  
  70.   
  71.         mButton_pause.setOnClickListener(new Button.OnClickListener()  
  72.             public void onClick(View v)  
  73.                 if (isPause)  
  74.                     Log.i(TAG, "Resume");  
  75.                 else  
  76.                     Log.i(TAG, "Pause");  
  77.                  
  78.   
  79.                 isPause !isPause;  
  80.   
  81.                 if (isPause)  
  82.                     mButton_pause.setText(R.string.resume);  
  83.                 else  
  84.                     mButton_pause.setText(R.string.pause);  
  85.                  
  86.              
  87.         });  
  88.           
  89.         mHandler new Handler(){  
  90.   
  91.             @Override  
  92.             public void handleMessage(Message msg)  
  93.                 switch (msg.what)  
  94.                 case UPDATE_TEXTVIEW:  
  95.                     updateTextView();  
  96.                     break 
  97.                 default 
  98.                     break 
  99.                  
  100.              
  101.         };  
  102.      
  103.   
  104.     private void updateTextView(){  
  105.         mTextView.setText(String.valueOf(count));  
  106.      
  107.   
  108.     private void startTimer(){  
  109.         if (mTimer == null 
  110.             mTimer new Timer();  
  111.          
  112.   
  113.         if (mTimerTask == null 
  114.             mTimerTask new TimerTask()  
  115.                 @Override  
  116.                 public void run()  
  117.                     Log.i(TAG, "count: "+String.valueOf(count));  
  118.                     sendMessage(UPDATE_TEXTVIEW);  
  119.                       
  120.                     do  
  121.                         try  
  122.                             Log.i(TAG, "sleep(1000)...");  
  123.                             Thread.sleep(1000);  
  124.                         catch (InterruptedException e)  
  125.                             
  126.                     while (isPause);  
  127.                       
  128.                     count ++;    
  129.                  
  130.             };  
  131.          
  132.   
  133.         if(mTimer != null && mTimerTask != null  
  134.             mTimer.schedule(mTimerTask, delay, period);  
  135.   
  136.      
  137.   
  138.     private void stopTimer(){  
  139.           
  140.         if (mTimer != null 
  141.             mTimer.cancel();  
  142.             mTimer null 
  143.          
  144.   
  145.         if (mTimerTask != null 
  146.             mTimerTask.cancel();  
  147.             mTimerTask null 
  148.             
  149.   
  150.         count 0 
  151.   
  152.      
  153.       
  154.     public void sendMessage(int id){  
  155.         if (mHandler != null 
  156.             Message message Message.obtain(mHandler, id);     
  157.             mHandler.sendMessage(message);   
  158.          
  159.      
  160.