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

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


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

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

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

  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. }  
package com.test.timertest;

/**
 * 对计时器的测试
 */
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.widget.TextView;

public class TimerActivity extends Activity {
	private TextView txtCount;
	private int count;
	
	//处理界面
	private  Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			if(msg.arg1 == 1){
				txtCount.setText(String.valueOf(count));
			}
		};
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		this.txtCount = (TextView)findViewById(R.id.count);
		new Timer().schedule(countTask, 10, 2000);  //延迟10毫秒,每2秒钟执行一次     
	}
	//任务
	TimerTask countTask = new TimerTask() {
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			count ++;
			Message msg = new Message();
			msg.arg1 = 1;
			handler.sendMessage(msg);
		}
	};
}
结果:

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

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

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

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

2.采用线程的Sleep处理;

  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. }  
package com.test.timertest;

/**
 * 对计时器的测试
 */
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.widget.TextView;

public class TimerActivity extends Activity {
	private TextView txtCount;
	private int count;
	
	//处理界面
	private  Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			if(msg.arg1 == 1){
				txtCount.setText(String.valueOf(count));
			}
		};
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		this.txtCount = (TextView)findViewById(R.id.count);
//		new Timer().schedule(countTask, 10, 2000);  //延迟10毫秒,每2秒钟执行一次     
		new CountThread().start();
		
		
	}
	
	class CountThread extends Thread{
		@Override
		public void run() {
			while(true){
				count ++;
				Message msg = new Message();
				msg.arg1 = 1;
				handler.sendMessage(msg);
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	
//	//任务
//	TimerTask countTask = new TimerTask() {
//		
//		@Override
//		public void run() {
//			// TODO Auto-generated method stub
//			count ++;
//			Message msg = new Message();
//			msg.arg1 = 1;
//			handler.sendMessage(msg);
//		}
//	};
}
采用Sleep的处理结果和上面1中的一样,怀疑是不是activity和thread有区别,于是采用线程来处理,并将结果保存到xml中

服务如下:

  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. }  
package com.test.timertest;

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

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.IBinder;

public class CountService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		new Timer().schedule(countTask, 10, 2000);   //2秒钟
	}

	// 任务
	TimerTask countTask = new TimerTask() {
		@Override
		public void run() {
			saveAppCount();
		}
	};

	// 保存数据
	private void saveAppCount() {
		int count = getAppCount() + 1;
		SharedPreferences sf = getSharedPreferences("appcount",
				Context.MODE_PRIVATE);
		Editor editor = sf.edit();
		editor.putInt("count", count);
		editor.commit();
	}

	// 获取数据
	public int getAppCount() {
		SharedPreferences spf = getSharedPreferences("appcount",
				Context.MODE_PRIVATE);
		return spf.getInt("count", 0);
	}
}

显示数据的activity


  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. }  
package com.test.timertest;

/**
 * 对计时器的测试
 */

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.TextView;

public class TimerActivity extends Activity {
	private TextView txtCount;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		this.txtCount = (TextView)findViewById(R.id.count);
		SharedPreferences spf = getSharedPreferences("appcount",
				Context.MODE_PRIVATE);
		int count =  spf.getInt("count", 0);
		txtCount.setText(String.valueOf(count));
		
		Intent intent = new Intent(this,CountService.class);
		startService(intent);
		
	}
	
}
测试结果::

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

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

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

  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. }  
package com.test.timertest;

/**
 * 对计时器的测试
 */

import java.util.Timer;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.SystemClock;
import android.widget.TextView;

public class TimerActivity extends Activity {
	private TextView txtCount;
	public final String ACTION = "com.test.timertest.alarmreciver";
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		this.txtCount = (TextView)findViewById(R.id.count);
		SharedPreferences spf = getSharedPreferences("appcount",
				Context.MODE_PRIVATE);
		int count =  spf.getInt("count", 0);
		txtCount.setText(String.valueOf(count));
		
//		Intent intent = new Intent(this,CountService.class);
//		startService(intent);
		
		//闹钟全局变量
		AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
		Intent intent = new Intent(ACTION);
		PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
		long firsttime = SystemClock.elapsedRealtime();
		firsttime  += 2*1000;
		am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,firsttime, 2*1000,sender);  //AlarmManager.ELAPSED_REALTIME_WAKEUP 这里要用这个类型的tiype才能保证系统在sleep的时候也能发广播,不懂的可以去看文档的介绍
		
	}
	
}

接受广播的类

  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. }  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值