计时器在活动关闭并重新启动后不会停止
我有一个每秒更新一次textview的runnable计时器,当活动处于onStop(或称为后台)计时器继续运行时。我遇到的问题是,当我重新启动活动时,它会再次启动相同的计时器,因此数字会以其应有的速度提高两倍。我把它编码,这样它会在重新启动它们之前杀死两个计时器,但我相信当活动再次启动时,计时器不会被杀死。下面是我的代码示例:计时器在活动关闭并重新启动后不会停止
t.cancel();
cd.cancel();
t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
那只是一小部分,但它应该终止计时器(t.cancel();),然后开始一个新的,当活动停止这只是发生和然后重新启动。请帮助这个问题让我绝对疯了。
============================================== ===========
对于愿意读很多的勇敢的灵魂,这里要说的是我有问题我的整个活动:
public class PayTracker extends Activity {
private static double Reserve;
private static int Reserve1;
public static double money;
public static double counter;
private static int go;
private static int countdown;
public static int convert;
public static double HW;
public static double OTW;
public static double HPD;
public static double DPPS;
public Timer t = new Timer();
public Timer cd = new Timer();
public static String mcountdown = "Time till overtime";
public static String mmoney = "total cash";
public static String mcounter = "ticks";
public static String mReserve = "building total";
public static String mReserve1 = "building total 2";
public static String mHW;
public static String mOTW;
public static String mHPD;
public static String mDPPS;
public static String mgo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pay_tracker);
getActionBar().setDisplayHomeAsUpEnabled(true);
// Receive messages from options page
double pHW, pOTW, pHPD;
Intent intent = getIntent();
pHW = intent.getDoubleExtra(Options.MESSAGE_HW, 0);
pOTW = intent.getDoubleExtra(Options.MESSAGE_OTW, 0);
pHPD = intent.getDoubleExtra(Options.MESSAGE_HPD, 0);
if(pHW != 0){
HW = pHW;
OTW = pOTW;
HPD = pHPD;
}
// Color buttons
Button buttonc = (Button) findViewById(R.id.clockin);
buttonc.getBackground().setColorFilter(0xFF00FF00, PorterDuff.Mode.MULTIPLY);
Button buttond = (Button) findViewById(R.id.clockout);
buttond.getBackground().setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
// go = 0;
// Calculate pay per second
final double PPS = (HW/3600);
DPPS = (PPS/50);
final double OTPPS = (OTW/3600);
final double DOTPPS = (OTPPS/50);
final double HPDPS = (HPD*3600);
final double DHPDPS = (HPDPS*50);
// Display
final TextView t1 = (TextView) findViewById(R.id.yourpay);
t1.setTextColor(Color.parseColor("#008000"));
final TextView t2 = (TextView) this.findViewById(R.id.payper);
final String result2 = String.format("%.8f", OTPPS);
final String result = String.format("%.8f", PPS);
// if(go != 1){
// go = 1;
// if(go == 1){
t.cancel();
cd.cancel();
// go = 0;
// }
// if(go == 0){
// go = 1;
t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
if(DHPDPS==0){
money = (DPPS+Reserve);
Reserve = (money);
String end = String.format("%1f", money);
t1.setText("$" + end);
}else if(counter > DHPDPS && DOTPPS != 0 && DHPDPS != 0){
money = (DOTPPS+Reserve);
Reserve = (money);
String end = String.format("%1f", money);
t1.setText("$" + end);
} else{
money = (DPPS+Reserve);
Reserve = (money);
String end = String.format("%1f", money);
t1.setText("$" + end);
}
counter++;
//if(counter == 3000)
// t.cancel();
// Display pay per second
if(counter <= DHPDPS || DHPDPS == 0){
t2.setText("Your pay per second is: $"+result);
}else{
t2.setText("Your pay per second is: $"+result2);
}
}
});
}
}, 20, 20);
// Make countdown to overtime display
final Intent intent1 = new Intent(this, PayTracker.class);
// Create the notification
final Notification notification = new Notification(R.drawable.ic_launcher, "Click here to check your pay!", System.currentTimeMillis());
// Create an Intent for the notification to launch
// Create a PendingIntent for the associated Intent
final PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent1, 0);
cd = new Timer();
final TextView count = (TextView) findViewById(R.id.countdown);
convert = (int)HPDPS;
cd.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
public void run(){
countdown = (convert - Reserve1);
int hours = (countdown/3600);
if(OTPPS != 0 && HPDPS != 0){
count.setText("Seconds Remaining to Overtime: " + countdown + "\nAbout " + hours + " Hours");
Reserve1++;
}
// Set the notification's details
final String end = String.format("%.6f", money);
notification.setLatestEventInfo(getApplicationContext(), "Your Current Pay:", "$"+end, pendingIntent);
// Submit the notification to the system
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(0, notification);
}
});
}
}, 1000, 1000);
// }
// }
final Button b = (Button) findViewById(R.id.clockout);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(go == 1)
go = 0;
if (t != null){
t.cancel();
cd.cancel();
}
}
});
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore value of members from saved state
countdown = savedInstanceState.getInt(mcountdown);
Reserve = savedInstanceState.getInt(mReserve);
money = savedInstanceState.getInt(mmoney);
counter = savedInstanceState.getInt(mcounter);
Reserve1 = savedInstanceState.getInt(mReserve1);
HW = savedInstanceState.getInt(mHW);
OTW = savedInstanceState.getInt(mOTW);
HPD = savedInstanceState.getInt(mHPD);
DPPS = savedInstanceState.getInt(mDPPS);
go = savedInstanceState.getInt(mgo);
}
@Override
public void onStart(){
super.onStart();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_pay_tracker, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
public void sendMessage(View view) {
// Calculate pay per second
final double PPS = (HW/3600);
DPPS = (PPS/50);
final double OTPPS = (OTW/3600);
final double DOTPPS = (OTPPS/50);
final double HPDPS = (HPD*3600);
final double DHPDPS = (HPDPS*50);
// Display
final TextView t1 = (TextView) findViewById(R.id.yourpay);
t1.setTextColor(Color.parseColor("#008000"));
final TextView t2 = (TextView) this.findViewById(R.id.payper);
final String result2 = String.format("%.8f", OTPPS);
final String result = String.format("%.8f", PPS);
//if(go != 1){
// go = 1;
t.cancel();
cd.cancel();
t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
if(DHPDPS==0){
money = (DPPS+Reserve);
Reserve = (money);
String end = String.format("%1f", money);
t1.setText("$" + end);
}else if(counter > DHPDPS && DOTPPS != 0 && DHPDPS != 0){
money = (DOTPPS+Reserve);
Reserve = (money);
String end = String.format("%1f", money);
t1.setText("$" + end);
} else{
money = (DPPS+Reserve);
Reserve = (money);
String end = String.format("%1f", money);
t1.setText("$" + end);
}
counter++;
if(counter == 3000)
t.cancel();
// Display pay per second
if(counter <= DHPDPS || DHPDPS == 0){
t2.setText("Your pay per second is: $"+result);
}else{
t2.setText("Your pay per second is: $"+result2);
}
}
});
}
}, 20, 20);
// Make countdown to overtime display
final Intent intent1 = new Intent(this, PayTracker.class);
// Create the notification
final Notification notification = new Notification(R.drawable.ic_launcher, "Click here to check your pay!", System.currentTimeMillis());
// Create an Intent for the notification to launch
// Create a PendingIntent for the associated Intent
final PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent1, 0);
cd = new Timer();
final TextView count = (TextView) findViewById(R.id.countdown);
convert = (int)HPDPS;
cd.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
public void run(){
countdown = (convert - Reserve1);
int hours = (countdown/3600);
if(OTPPS != 0 && HPDPS != 0){
count.setText("Seconds Remaining to Overtime: " + countdown + "\nAbout " + hours + " Hours");
Reserve1++;
}
// Set the notification's details
final String end = String.format("%.6f", money);
notification.setLatestEventInfo(getApplicationContext(), "Your Current Pay:", "$"+end, pendingIntent);
// Submit the notification to the system
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(0, notification);
}
});
}
}, 1000, 1000);
//}
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(mcountdown, countdown);
savedInstanceState.putDouble(mReserve, Reserve);
savedInstanceState.putDouble(mmoney, money);
savedInstanceState.putDouble(mcounter, counter);
savedInstanceState.putDouble(mReserve1, Reserve1);
savedInstanceState.putDouble(mHW, HW);
savedInstanceState.putDouble(mOTW, OTW);
savedInstanceState.putDouble(mHPD, HPD);
savedInstanceState.putDouble(mDPPS, DPPS);
savedInstanceState.putInt(mgo, go);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onDestroy() {
super.onDestroy();
if(t != null)
t.cancel();
if(cd != null)
cd.cancel();
}
}
这是获得一种方式在那附近。
static Timer mTimer = null;
onCreate() {
if (mTimer == null)
mTimer = new Timer();
} else {
// You shouldn't have to do nothing because your timer should be running
}
}
请注意,这里一般有几个问题。静态基本上只是说创建该对象的一个实例。作为副作用,它也试图回收相同的内存地址。无论哪种方式,一旦你的应用程序在后台,它可以在任何时候由系统清理,所以你不能保证让你的定时器回来。还有其他一些方法可以解决这个问题,但这个问题超出了范围。
您能解释一些其他方式来解决在后台有计时器吗?我知道它不是针对这个问题,但它会帮助我很大程度上与我的项目,即时通讯新的android编程,所以即时通讯仍然试图学习 – Hockeyman271 2012-08-07 20:50:39
张贴的问题,并发送给我的链接 – 2012-08-07 20:51:41
我会尽快我有时间,但我试过这种方法和它的工作原理,唯一的问题是现在我的用户界面不会在活动重新启动时更新?我可以在我的通知栏中看到计时器仍在运行,但用户界面不会填充 – Hockeyman271 2012-08-07 20:59:33
运行中是否存在while循环? – 2012-08-07 20:23:34
@Andi Jay no theres不是 – Hockeyman271 2012-08-07 20:24:49
你能不能在'onStop()'中调用'Timer.cancel()'? – 2012-08-07 20:25:04