java Timer计时器在android中运行时出现的问题

来源:互联网 发布:蚂蚁金服 java 工资 编辑:程序博客网 时间:2024/06/05 00:12

转摘自:http://blog.csdn.net/lzqjfly/article/details/8021551


目标: 希望采用Timer来计时,要求在服务中运行,每10分钟记录一次数据。但是采用timer来做了以后,发现统计的次数没有达到预期的目标。甚至没有运行,以下是在测试情况

1.为了能够看到测试效果,将循环时间设置为2秒

本打算用服务做测试,但为了方便就用activity做测试

[java] view plaincopyprint?
  1. package com.test.timertest;  
  2.   
  3. /** 
  4.  * 对计时器的测试 
  5.  */  
  6. import java.util.Timer;  
  7. import java.util.TimerTask;  
  8.   
  9. import android.app.Activity;  
  10. import android.os.Bundle;  
  11. import android.os.Handler;  
  12. import android.os.Message;  
  13. import android.widget.TextView;  
  14.   
  15. public class TimerActivity extends Activity {  
  16.     private TextView txtCount;  
  17.     private int count;  
  18.       
  19.     //处理界面   
  20.     private  Handler handler = new Handler(){  
  21.         public void handleMessage(android.os.Message msg) {  
  22.             if(msg.arg1 == 1){  
  23.                 txtCount.setText(String.valueOf(count));  
  24.             }  
  25.         };  
  26.     };  
  27.       
  28.     @Override  
  29.     protected void onCreate(Bundle savedInstanceState) {  
  30.         // TODO Auto-generated method stub   
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.activity_main);  
  33.         this.txtCount = (TextView)findViewById(R.id.count);  
  34.         new Timer().schedule(countTask, 102000);  //延迟10毫秒,每2秒钟执行一次       
  35.     }  
  36.     //任务   
  37.     TimerTask countTask = new TimerTask() {  
  38.           
  39.         @Override  
  40.         public void run() {  
  41.             // TODO Auto-generated method stub  
  42.             count ++;  
  43.             Message msg = new Message();  
  44.             msg.arg1 = 1;  
  45.             handler.sendMessage(msg);  
  46.         }  
  47.     };  
  48. }  
结果:

1.将手机与电脑连接测试,改程序正常,能够一直运行。并且按下电源键后仍然能够正常运行,统计的次数也正常

2.手机与电脑断开连接后,然后重新运行改程序,该程序能正常运行。然后按下电源键,手机处于待机状态,过一段时间后在看屏幕上的次数,发现次数没有动,不知道为啥???

3.手机与电脑断开连接后,运行程序,然后按home键,在手机没有处于待机的状态下,统计的次数发生变化,能够正常运行。但是如果手机处于待机状态后,程序不在运行。

问题: 手机待机后会让大部分程序不在运行(除电话,短信等)。难道这是系统的保护机制???  

2.采用线程的Sleep处理;

[java] view plaincopyprint?
  1. package com.test.timertest;  
  2.   
  3. /** 
  4.  * 对计时器的测试 
  5.  */  
  6. import java.util.Timer;  
  7. import java.util.TimerTask;  
  8.   
  9. import android.app.Activity;  
  10. import android.os.Bundle;  
  11. import android.os.Handler;  
  12. import android.os.Message;  
  13. import android.widget.TextView;  
  14.   
  15. public class TimerActivity extends Activity {  
  16.     private TextView txtCount;  
  17.     private int count;  
  18.       
  19.     //处理界面   
  20.     private  Handler handler = new Handler(){  
  21.         public void handleMessage(android.os.Message msg) {  
  22.             if(msg.arg1 == 1){  
  23.                 txtCount.setText(String.valueOf(count));  
  24.             }  
  25.         };  
  26.     };  
  27.       
  28.     @Override  
  29.     protected void onCreate(Bundle savedInstanceState) {  
  30.         // TODO Auto-generated method stub   
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.activity_main);  
  33.         this.txtCount = (TextView)findViewById(R.id.count);  
  34. //      new Timer().schedule(countTask, 10, 2000);  //延迟10毫秒,每2秒钟执行一次       
  35.         new CountThread().start();  
  36.           
  37.           
  38.     }  
  39.       
  40.     class CountThread extends Thread{  
  41.         @Override  
  42.         public void run() {  
  43.             while(true){  
  44.                 count ++;  
  45.                 Message msg = new Message();  
  46.                 msg.arg1 = 1;  
  47.                 handler.sendMessage(msg);  
  48.                 try {  
  49.                     Thread.sleep(2000);  
  50.                 } catch (InterruptedException e) {  
  51.                     // TODO Auto-generated catch block  
  52.                     e.printStackTrace();  
  53.                 }  
  54.             }  
  55.         }  
  56.     }  
  57.       
  58.       
  59. //  //任务   
  60. //  TimerTask countTask = new TimerTask() {   
  61. //         
  62. //      @Override   
  63. //      public void run() {   
  64. //          // TODO Auto-generated method stub   
  65. //          count ++;   
  66. //          Message msg = new Message();   
  67. //          msg.arg1 = 1;   
  68. //          handler.sendMessage(msg);   
  69. //      }   
  70. //  };   
  71. }  
采用Sleep的处理结果和上面1中的一样,怀疑是不是activity和thread有区别,于是采用线程来处理,并将结果保存到xml中

服务如下:

[java] view plaincopyprint?
  1. package com.test.timertest;  
  2.   
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. import android.app.Service;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.content.SharedPreferences;  
  10. import android.content.SharedPreferences.Editor;  
  11. import android.os.IBinder;  
  12.   
  13. public class CountService extends Service {  
  14.   
  15.     @Override  
  16.     public IBinder onBind(Intent intent) {  
  17.         // TODO Auto-generated method stub   
  18.         return null;  
  19.     }  
  20.   
  21.     @Override  
  22.     public void onCreate() {  
  23.         // TODO Auto-generated method stub   
  24.         super.onCreate();  
  25.         new Timer().schedule(countTask, 102000);   //2秒钟  
  26.     }  
  27.   
  28.     // 任务   
  29.     TimerTask countTask = new TimerTask() {  
  30.         @Override  
  31.         public void run() {  
  32.             saveAppCount();  
  33.         }  
  34.     };  
  35.   
  36.     // 保存数据   
  37.     private void saveAppCount() {  
  38.         int count = getAppCount() + 1;  
  39.         SharedPreferences sf = getSharedPreferences("appcount",  
  40.                 Context.MODE_PRIVATE);  
  41.         Editor editor = sf.edit();  
  42.         editor.putInt("count", count);  
  43.         editor.commit();  
  44.     }  
  45.   
  46.     // 获取数据   
  47.     public int getAppCount() {  
  48.         SharedPreferences spf = getSharedPreferences("appcount",  
  49.                 Context.MODE_PRIVATE);  
  50.         return spf.getInt("count"0);  
  51.     }  
  52. }  

显示数据的activity


[java] view plaincopyprint?
  1. package com.test.timertest;  
  2.   
  3. /** 
  4.  * 对计时器的测试 
  5.  */  
  6.   
  7. import android.app.Activity;  
  8. import android.content.Context;  
  9. import android.content.Intent;  
  10. import android.content.SharedPreferences;  
  11. import android.os.Bundle;  
  12. import android.widget.TextView;  
  13.   
  14. public class TimerActivity extends Activity {  
  15.     private TextView txtCount;  
  16.       
  17.     @Override  
  18.     protected void onCreate(Bundle savedInstanceState) {  
  19.         // TODO Auto-generated method stub   
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.activity_main);  
  22.         this.txtCount = (TextView)findViewById(R.id.count);  
  23.         SharedPreferences spf = getSharedPreferences("appcount",  
  24.                 Context.MODE_PRIVATE);  
  25.         int count =  spf.getInt("count"0);  
  26.         txtCount.setText(String.valueOf(count));  
  27.           
  28.         Intent intent = new Intent(this,CountService.class);  
  29.         startService(intent);  
  30.           
  31.     }  
  32.       
  33. }  
测试结果::

1.手机和电脑连接,手机处于调试模式,不管是按下电源键让手机处于待机状态还是按下home键,服务都能够正常的统计数据

2.手机与电脑断开连接,不管是手机自动处于待机状态还是主动按下电源键让手机处于待机状态,服务里面的线程都没有正常的记录数据。 求解 ???

最终结合网上资料采用AlarmManager 控制计时操作,能够保证系统在sleep的时候发出广播,达到统计的目的

[java] view plaincopyprint?
  1. package com.test.timertest;  
  2.   
  3. /** 
  4.  * 对计时器的测试 
  5.  */  
  6.   
  7. import java.util.Timer;  
  8.   
  9. import android.app.Activity;  
  10. import android.app.AlarmManager;  
  11. import android.app.PendingIntent;  
  12. import android.content.Context;  
  13. import android.content.Intent;  
  14. import android.content.SharedPreferences;  
  15. import android.os.Bundle;  
  16. import android.os.SystemClock;  
  17. import android.widget.TextView;  
  18.   
  19. public class TimerActivity extends Activity {  
  20.     private TextView txtCount;  
  21.     public final String ACTION = "com.test.timertest.alarmreciver";  
  22.       
  23.     @Override  
  24.     protected void onCreate(Bundle savedInstanceState) {  
  25.         // TODO Auto-generated method stub   
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.activity_main);  
  28.         this.txtCount = (TextView)findViewById(R.id.count);  
  29.         SharedPreferences spf = getSharedPreferences("appcount",  
  30.                 Context.MODE_PRIVATE);  
  31.         int count =  spf.getInt("count"0);  
  32.         txtCount.setText(String.valueOf(count));  
  33.           
  34. //      Intent intent = new Intent(this,CountService.class);  
  35. //      startService(intent);   
  36.           
  37.         //闹钟全局变量   
  38.         AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);  
  39.         Intent intent = new Intent(ACTION);  
  40.         PendingIntent sender = PendingIntent.getBroadcast(this0, intent, 0);  
  41.         long firsttime = SystemClock.elapsedRealtime();  
  42.         firsttime  += 2*1000;  
  43.         am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,firsttime, 2*1000,sender);  //AlarmManager.ELAPSED_REALTIME_WAKEUP 这里要用这个类型的tiype才能保证系统在sleep的时候也能发广播,不懂的可以去看文档的介绍  
  44.           
  45.     }  
  46.       
  47. }  

接受广播的类

[java] view plaincopyprint?
  1. package com.test.timertest;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.content.SharedPreferences;  
  7. import android.content.SharedPreferences.Editor;  
  8.   
  9. public class AlarmReciver extends BroadcastReceiver {  
  10.   
  11.     @Override  
  12.     public void onReceive(Context context, Intent intent) {  
  13.         // TODO Auto-generated method stub   
  14.         saveAppCount(context);  
  15.     }  
  16.   
  17.     // 保存数据   
  18.     private void saveAppCount(Context context) {  
  19.         int count = getAppCount(context) + 1;  
  20.         SharedPreferences sf = context.getSharedPreferences("appcount",  
  21.                 Context.MODE_PRIVATE);  
  22.         Editor editor = sf.edit();  
  23.         editor.putInt("count", count);  
  24.         editor.commit();  
  25.     }  
  26.   
  27.     // 获取数据   
  28.     public int getAppCount(Context context) {  
  29.         SharedPreferences spf = context.getSharedPreferences("appcount",  
  30.                 Context.MODE_PRIVATE);  
  31.         return spf.getInt("count"0);  
  32.     }  
  33. }