该服务的目的是跟踪按下按钮后的时间。如果菜单 Activity 正在显示,它会使用计时器每分钟更新菜单 Activity 上的一些值,否则,它只会更新自己。
当应用程序打开或关闭时,它似乎工作正常,但当手机关闭时,它的速度会减慢到应有速度的一半以下(仅在 21 实际分钟过去后才显示 10 分钟过去了)。
int startTime; //time at which the button is pressed
int time; //the current time, relative to startTime
@Override
public int onStartCommand(Intent intent, int flags, int startId){
startTime = (int)(System.nanoTime()/1000000000.0);
UpdateTimeTask updateTimeTask = new UpdateTimeTask();
timer = new Timer();
timer.schedule(updateTimeTask, 0, UPDATE_PERIOD); //update period is 60,000 (60 seconds)
return START_STICKY;
}
public class UpdateTimeTask extends TimerTask {
public void run() {
updateMenu();
}
}
public void updateMenu(){
time = (int) Math.round((System.nanoTime() / 1000000000.0) - startTime);
if(serviceCallbacks != null){ //it wont be null if its on menuactivity
serviceCallbacks.updateTimeElapsed(time/3600, time/60 - (time/3600) * 60);
}
}
如果我将手机关闭一段时间然后返回菜单 Activity ,则几个周期后它不会“自行修复”。我认为 onStartCommand 可能会被多次调用,但唯一可能启动服务的时间是按下按钮时。
最佳答案
but the only time the service can possibly be started is when the button is pressed
事实并非如此。当您的应用程序进入后台(不再可见)时,如果系统需要其他排名较高的应用程序的内存,它就会成为被杀死的候选者。此外,用户可以通过从任务列表中滑动来终止您的应用程序。由于服务从 onStartCommand()
返回 START_STICKY
,因此系统会在一段时间后重新启动服务,并以 null 调用 onStartCommand()
Intent 。此行为使得服务不适合作为您要保留的数据项的所在地,例如 startTime
。
另一种方法是将值保留在 SharedPreferences 中。不需要服务,可以使用 postDelayed() 在您的 Activity 中完成定期更新处理。任何 View 的方法。
此示例 Activity 概述了基本逻辑:
public class ButtonActivity extends Activity {
private static final String TIME_KEY = "time";
private static final long PERIOD = 60*1000; // 60 seconds
private SharedPreferences mPrefs;
private Button mButton;
private TextView mTimeView;
private Runnable mDisplayTask = new Runnable() {
@Override
public void run() {
// show the time elapsed since button press in milliseconds
long elapsed = System.currentTimeMillis() - mPrefs.getLong(TIME_KEY, 0);
mTimeView.setText(""+elapsed);
// schedule next display update
mTimeView.postDelayed(mDisplayTask, PERIOD);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPrefs = getPreferences(MODE_PRIVATE);
// clear the button press time
setPressTime(0);
setContentView(R.layout.activity_demo);
mButton = (Button)findViewById(R.id.button);
mTimeView = (TextView)findViewById(R.id.time);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// save the button press time
setPressTime(System.currentTimeMillis());
// start the display updates
mDisplayTask.run();
}
});
}
@Override
protected void onPause() {
super.onPause();
// activity no longer visible; stop the updates
mTimeView.removeCallbacks(mDisplayTask);
}
@Override
protected void onResume() {
super.onResume();
// activity is visible
// if the button has been pressed, start the display updates
if (mPrefs.getLong(TIME_KEY, 0) > 0) {
mDisplayTask.run();
}
}
private void setPressTime(long time) {
// persist the button press time
SharedPreferences.Editor ed = mPrefs.edit();
ed.putLong(TIME_KEY, time);
ed.commit();
}
}
关于java - 当电话关闭时,我的服务表现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34629520/