加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

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

(2012-10-23 20:31:24)
标签:

定时器

utf-8

控件

组件

提示

it

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

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

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

  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 
D/AndroidRuntime( 6672): Shutting down VM
W/dalvikvm( 6672): threadid=1: thread exiting with uncaught exception (group=0x40018560)
E/AndroidRuntime( 6672): FATAL EXCEPTION: main
E/AndroidRuntime( 6672): java.lang.IllegalStateException: Timer was canceled
E/AndroidRuntime( 6672):        at java.util.Timer.scheduleImpl(Timer.java:563)
E/AndroidRuntime( 6672):        at java.util.Timer.schedule(Timer.java:483)
E/AndroidRuntime( 6672):        at com.snowdream.timerdemo.TimerDemoActivity$2.onClick(TimerDemoActivity.java:73)
E/AndroidRuntime( 6672):        at android.view.View.performClick(View.java:2501)
E/AndroidRuntime( 6672):        at android.view.View$PerformClick.run(View.java:9107)
E/AndroidRuntime( 6672):        at android.os.Handler.handleCallback(Handler.java:587)
E/AndroidRuntime( 6672):        at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime( 6672):        at android.os.Looper.loop(Looper.java:130)
E/AndroidRuntime( 6672):        at android.app.ActivityThread.main(ActivityThread.java:3835)
E/AndroidRuntime( 6672):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 6672):        at java.lang.reflect.Method.invoke(Method.java:507)
E/AndroidRuntime( 6672):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
E/AndroidRuntime( 6672):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
E/AndroidRuntime( 6672):        at dalvik.system.NativeStart.main(Native Method)
W/ActivityManager(  154):   Force finishing activity com.snowdream.timerdemo/.TimerDemoActivity
W/ActivityManager(  154): Activity pause timeout for HistoryRecord{40550560 com.snowdream.timerdemo/.TimerDemoActivity}
W/ActivityManager(  154): Activity destroy timeout for HistoryRecord{40550560 com.snowdream.timerdemo/.TimerDemoActivity}
D/dalvikvm(  800): GC_EXPLICIT freed 13K, 58% free 3127K/7431K, external 0K/0K, paused 70ms
D/dalvikvm(  562): GC_EXPLICIT freed 59K, 51% free 2935K/5959K, external 245K/512K, paused 84ms
I/ActivityManager(  154): Start proc com.android.email for service com.android.email/.service.MailService: pid=6691 uid=10019 gids={3003, 1015}

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

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

  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 
E/AndroidRuntime( 6309): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime( 6309):        at android.view.ViewRoot.checkThread(ViewRoot.java:2941)
E/AndroidRuntime( 6309):        at android.view.ViewRoot.invalidateChild(ViewRoot.java:643)
E/AndroidRuntime( 6309):        at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:669)
E/AndroidRuntime( 6309):        at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
E/AndroidRuntime( 6309):        at android.view.View.invalidate(View.java:5296)
E/AndroidRuntime( 6309):        at android.widget.TextView.checkForRelayout(TextView.java:5533)
E/AndroidRuntime( 6309):        at android.widget.TextView.setText(TextView.java:2730)
E/AndroidRuntime( 6309):        at android.widget.TextView.setText(TextView.java:2598)
E/AndroidRuntime( 6309):        at android.widget.TextView.setText(TextView.java:2573)
E/AndroidRuntime( 6309):        at com.snowdream.timerdemo.TimerDemoActivity$1.run(TimerDemoActivity.java:48)
E/AndroidRuntime( 6309):        at java.util.Timer$TimerImpl.run(Timer.java:284)


Demo源码如下:

TimerDemoActivity.java

  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.  
package com.snowdream.timerdemo;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class TimerDemoActivity extends Activity {

        private static String  TAG = "TimerDemo";

        private TextView mTextView = null;
        private Button mButton_start = null;
        private Button mButton_pause = null;

        private Timer mTimer = null;
        private TimerTask mTimerTask = null;

        private Handler mHandler = null;
        
        private static int count = 0;
        private boolean isPause = false;
        private boolean isStop = true;

        private static int delay = 1000;  //1s
        private static int period = 1000;  //1s

        private static final int UPDATE_TEXTVIEW = 0;
        
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);

                mTextView = (TextView)findViewById(R.id.mytextview); 
                mButton_start = (Button)findViewById(R.id.mybutton_start);
                mButton_pause = (Button)findViewById(R.id.mybutton_pause);


                mButton_start.setOnClickListener(new Button.OnClickListener() {
                        public void onClick(View v) {
                                if (isStop) {
                                        Log.i(TAG, "Start");
                                } else {
                                        Log.i(TAG, "Stop");
                                }

                                isStop = !isStop;

                                if (!isStop) {
                                        startTimer();
                                }else {
                                        stopTimer();
                                }

                                if (isStop) {
                                        mButton_start.setText(R.string.start);
                                } else {
                                        mButton_start.setText(R.string.stop);
                                }
                        }
                });

                mButton_pause.setOnClickListener(new Button.OnClickListener() {
                        public void onClick(View v) {
                                if (isPause) {
                                        Log.i(TAG, "Resume");
                                } else {
                                        Log.i(TAG, "Pause");
                                }

                                isPause = !isPause;

                                if (isPause) {
                                        mButton_pause.setText(R.string.resume);
                                } else {
                                        mButton_pause.setText(R.string.pause);
                                }
                        }
                });
                
                mHandler = new Handler(){

                        @Override
                        public void handleMessage(Message msg) {
                                switch (msg.what) {
                                case UPDATE_TEXTVIEW:
                                        updateTextView();
                                        break;
                                default:
                                        break;
                                }
                        }
                };
        }

        private void updateTextView(){
                mTextView.setText(String.valueOf(count));
        }

        private void startTimer(){
                if (mTimer == null) {
                        mTimer = new Timer();
                }

                if (mTimerTask == null) {
                        mTimerTask = new TimerTask() {
                                @Override
                                public void run() {
                                        Log.i(TAG, "count: "+String.valueOf(count));
                                        sendMessage(UPDATE_TEXTVIEW);
                                        
                                        do {
                                                try {
                                                        Log.i(TAG, "sleep(1000)...");
                                                        Thread.sleep(1000);
                                                } catch (InterruptedException e) {
                                                }       
                                        } while (isPause);
                                        
                                        count ++;  
                                }
                        };
                }

                if(mTimer != null && mTimerTask != null )
                        mTimer.schedule(mTimerTask, delay, period);

        }

        private void stopTimer(){
                
                if (mTimer != null) {
                        mTimer.cancel();
                        mTimer = null;
                }

                if (mTimerTask != null) {
                        mTimerTask.cancel();
                        mTimerTask = null;
                }       

                count = 0;

        }
        
        public void sendMessage(int id){
                if (mHandler != null) {
                        Message message = Message.obtain(mHandler, id);   
                        mHandler.sendMessage(message); 
                }
        }
}



layout-main.xml

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有