目标: 希望采用Timer来计时,要求在服务中运行,每10分钟记录一次数据。但是采用timer来做了以后,发现统计的次数没有达到预期的目标。甚至没有运行,以下是在测试情况1.为了能够看到测试效果,将循环时间设置为2秒
本打算用服务做测试,但为了方便就用activity做测试
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处理;
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中
服务如下:
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
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的时候发出广播,达到统计的目的
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的时候也能发广播,不懂的可以去看文档的介绍
}
}
接受广播的类
package com.test.timertest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class AlarmReciver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
saveAppCount(context);
}
// 保存数据
private void saveAppCount(Context context) {
int count = getAppCount(context) + 1;
SharedPreferences sf = context.getSharedPreferences("appcount",
Context.MODE_PRIVATE);
Editor editor = sf.edit();
editor.putInt("count", count);
editor.commit();
}
// 获取数据
public int getAppCount(Context context) {
SharedPreferences spf = context.getSharedPreferences("appcount",
Context.MODE_PRIVATE);
return spf.getInt("count", 0);
}
}