java - Android - 即使应用程序关闭时也在后台计算时间

标签 java android timer

我有一个textview,它充当步进计时器。我使用了一个处理程序并每秒更新它并且它工作得很好。但是当我关闭应用程序并打开时,计时器从“0”开始。我希望时间在后台运行,当我打开 Activity 时,应该显示耗时,而不是再次从 0 开始。显示时间格式为00:00:00

我的代码是

public class GoOnlinePage extends Activity { 

private TextView Tv_timer;
private Handler onlineTimeHandler = new Handler();
private long startTime = 0L;
private long timeInMilliseconds = 0L;
private long timeSwapBuff = 0L;
private long updatedTime = 0L;
private int mins;
private int secs;
private int hours;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.go_online_page);

    Tv_timer = (TextView) findViewById(R.id.txt_timer);

     startTime = SystemClock.uptimeMillis();

    onlineTimeHandler.post(updateTimerThread);


  }



  private Runnable updateTimerThread = new Runnable() {

    public void run() {

        timeInMilliseconds = SystemClock.uptimeMillis() - startTime;

        updatedTime = timeSwapBuff + timeInMilliseconds;

        secs = (int) (updatedTime / 1000);
        hours = secs / (60 * 60);
        mins = secs / 60;
        secs = secs % 60;
        if (mins >= 60) {
            mins = 0;
        }


        Tv_timer.setText(String.format("%02d", hours) + ":" + 
         String.format("%02d", mins) + ":"
                + String.format("%02d", secs));



        onlineTimeHandler.postDelayed(this, 1 * 1000);

    }

};

}

我尝试使用 session 并在updateTimerThread内每秒更新时间。当我重新打开应用程序时,我获取当前时间并找到两个时间之间的差异并更新计时器。但没有任何效果。

请帮助我。提前致谢。

编辑

已解决

我通过使用服务解决了这个问题,并使用BroadcastReceiver更新了textview。我附上了下面的代码供您引用。

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;



public class TimerService extends Service {
    private static String LOG_TAG = "TimerService";
    private IBinder mBinder = new MyBinder();

    Handler onlineTimeHandler = new Handler();
    long startTime = 0L, timeInMilliseconds = 0L, timeSwapBuff = 0L, updatedTime = 0L;
    int mins, secs, hours;
    String time = "";

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.v(LOG_TAG, "in onCreate");
        startTime = SystemClock.uptimeMillis();
        onlineTimeHandler.post(updateTimerThread);
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.v(LOG_TAG, "in onBind");
        return mBinder;
    }

    @Override
    public void onRebind(Intent intent) {
        Log.v(LOG_TAG, "in onRebind");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.v(LOG_TAG, "in onUnbind");
        return true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v(LOG_TAG, "in onDestroy");
        if(onlineTimeHandler!=null){
            onlineTimeHandler.removeCallbacks(updateTimerThread);
        }
    }


    public class MyBinder extends Binder {
        TimerService getService() {
            return TimerService.this;
        }
    }

    private Runnable updateTimerThread = new Runnable() {

        public void run() {

            timeInMilliseconds = SystemClock.uptimeMillis() - startTime;

            updatedTime = timeSwapBuff + timeInMilliseconds;

            secs = (int) (updatedTime / 1000);
            hours = secs / (60 * 60);
            mins = secs / 60;
            secs = secs % 60;
            if (mins >= 60) {
                mins = 0;
            }

            time = String.format("%02d", hours) + ":" + String.format("%02d", mins) + ":"
                    + String.format("%02d", secs);


            Intent intent = new Intent();
            intent.setAction("com.app.Timer.UpdateTime");
            intent.putExtra("time", time);
            sendBroadcast(intent);

            onlineTimeHandler.postDelayed(this, 1 * 1000);

        }

    };
}

最佳答案

使用一些静态变量非常简单。 即使 Activity 位于后台或已被销毁,此示例也会继续计数,不需要 SharedPreferences 或服务:

public class MainActivity extends AppCompatActivity {

    private static TextView txtCounter;
    private static Handler handler;
    private static Runnable runnable ;
    private static int count;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtCounter = (TextView) findViewById(R.id.txtCounter);
        if (handler == null) {
            handler = new Handler();
            runnable = new Runnable() {
                @Override
                public void run() {
                    txtCounter.setText("Count = " + count);
                    count++;
                    handler.postDelayed(runnable, 1000);
                }
            };
            handler.postDelayed(runnable, 1000);
        }
    }

}

更新:

暂停:handler.removeCallbacks(runnable);

恢复:handler.postDelayed(runnable, 1000);

重置计数器:count = 0;

关于java - Android - 即使应用程序关闭时也在后台计算时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45480373/

相关文章:

java - android.support.v7.widget.AppCompatTextView 无法转换为 android.widget.RelativeLayout

android - Android Studio 中的意外 token 错误

javascript - 如何为图像设置计时器以在 javascript 或 html 中显示?

c# - 如何同步定时器事件?

PHP Hit Counter...我可以将 SESSION 转换为 COOKIE 吗?

java - 为什么我的alertDialog.setMessage() 得到空值?

java - XmlPullParser 找不到名称中带有冒号的属性

java - HttpURLConnection:getResponseMessage()、getInputStream() 和 getContent() 之间的区别

android - 在 res/values/string.xml 中定义字符串?

android - opencv manager 是强制安装的吗?