android service using SystemClock.elapsedRealTime(

2019-08-31 02:47发布

问题:

First question here in stackoverflow :)

I'm running a little android 2.2 app to log cpu frequency usage. It is set up as a service that will write the data every 10 seconds using a new thread. The code for that part is very basic (see below).

It works fine, except that it would not keep track of time while the phone is asleep (which, I know, is the expected behavior). Thus, I changed the code to use SystemClock.elapsedRealTime() instead. Problem is, in emulator both commands are equivalent, but in the phone the app will start the thread but it will never execute the mHandler.postAtTime command. Any advice regarding why this is happening or how to overcome the issue is greatly appreciated.

PS: stopLog() is not being called. That's not the problem.

    mUpdateTimeTask = new Runnable() {
        public void run() {
            long millis = SystemClock.uptimeMillis() - mStartTime;
            int seconds = (int) (millis / 1000);
            int minutes = seconds / 60;
            seconds     = seconds % 60;

            String freq = readCPU ();
            if (freq == null)
                Toast.makeText(CPU_log_Service.this, "CPU frequency is unreadable.\nPlease make sure the file has read rights.", Toast.LENGTH_LONG).show();
            String str = new String ((minutes*60 + seconds) + ", " + freq + "\n");
            if (!writeLog (str)) stopLog();
            mHandler.postAtTime(this, mStartTime + (((minutes * 60) + seconds + 10) * 1000));
    }};

    mStartTime = SystemClock.uptimeMillis();
    mHandler.removeCallbacks(mUpdateTimeTask);
    mHandler.postDelayed(mUpdateTimeTask, 100);

回答1:

As the documentation states, for postAtTime(), "The time-base is uptimeMillis()." Hence, you cannot just decide to use elapsedRealTime().

I would recommend you simply use postDelayed(), to eliminate the whole time-base problem.