Java 我的服务在手机关机时表现得很奇怪
这项服务的目的是跟踪按钮按下后的时间。如果显示menuactivity,它会使用计时器每分钟更新menuactivity上的一些值,否则,它只会更新自身 当应用程序打开或关闭时,它似乎可以正常工作,但当手机关闭时,它的速度会降低到不到应有速度的一半(实际21分钟过去后仅显示10分钟过去了) 如果我关机一段时间后又回到menuactivity,它在几个周期后不会“自行修复”。我认为onStartCommand可能会被多次调用,但唯一可能启动服务的时间是按下按钮时 但该服务唯一可能启动的时间是 按钮按下了 事实并非如此。当你的应用程序进入后台(不再可见)时,如果系统需要内存用于其他排名较高的应用程序,它将成为被杀死的候选应用程序。此外,用户可以通过从任务列表中滑动应用程序来终止应用程序。由于服务从Java 我的服务在手机关机时表现得很奇怪,java,android,service,timer,Java,Android,Service,Timer,这项服务的目的是跟踪按钮按下后的时间。如果显示menuactivity,它会使用计时器每分钟更新menuactivity上的一些值,否则,它只会更新自身 当应用程序打开或关闭时,它似乎可以正常工作,但当手机关闭时,它的速度会降低到不到应有速度的一半(实际21分钟过去后仅显示10分钟过去了) 如果我关机一段时间后又回到menuactivity,它在几个周期后不会“自行修复”。我认为onStartCommand可能会被多次调用,但唯一可能启动服务的时间是按下按钮时 但该服务唯一可能启动的时间是 按钮
onStartCommand()
返回START\u
,系统将在一段时间后重新启动服务,并以空意图调用onStartCommand()
。此行为使服务不适合作为要保留的数据项的主项,例如startTime
另一种方法是将值持久化。不需要服务,可以使用任何视图的方法在活动中完成定期更新处理
此示例活动概述了基本逻辑:
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();
}
}
但该服务唯一可能启动的时间是
按钮按下了
事实并非如此。当你的应用程序进入后台(不再可见)时,如果系统需要内存用于其他排名较高的应用程序,它将成为被杀死的候选应用程序。此外,用户可以通过从任务列表中滑动应用程序来终止应用程序。由于服务从onStartCommand()
返回START\u
,系统将在一段时间后重新启动服务,并以空意图调用onStartCommand()
。此行为使服务不适合作为要保留的数据项的主项,例如startTime
另一种方法是将值持久化。不需要服务,可以使用任何视图的方法在活动中完成定期更新处理
此示例活动概述了基本逻辑:
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();
}
}
公认的答案是正确的,但只解决了部分问题。另一个问题是我使用的是System.nanoTime()而不是.currentTimeMillis()。当屏幕关闭时,nanoTime()停止。这是为未来可能的谷歌用户准备的。公认的答案是正确的,但只解决了部分问题。另一个问题是我使用的是System.nanoTime()而不是.currentTimeMillis()。当屏幕关闭时,nanoTime()停止。把这个放在这里给未来可能的谷歌用户。好的,这很有帮助。但服务也应该在经过一定时间后向用户发送通知。系统自动重启服务需要多长时间?@grey00:未指定时间。我的经验是,当应用程序被任务列表中的一次刷击杀死时,不到一分钟就会重新启动。当应用程序由于内存压力而被终止时,它将在内存可用之前不会重新启动。好的,谢谢,当它以空意图重新启动时,意图本身是空的还是空的?这似乎很奇怪,因为如果您使用了intents extras并且不知道,它会破坏代码。@grey00:intent参数是
null
,如图所示。我应该更正我之前的评论,当没有发出其他启动命令且处于挂起状态时,意图是null
。好的,这很有帮助。但服务也应该在经过一定时间后向用户发送通知。系统自动重启服务需要多长时间?@grey00:未指定时间。我的经验是,当应用程序被任务列表中的一次刷击杀死时,不到一分钟就会重新启动。当应用程序由于内存压力而被终止时,它将在内存可用之前不会重新启动。好的,谢谢,当它以空意图重新启动时,意图本身是空的还是空的?这似乎很奇怪,因为如果您使用了intents extras并且不知道,它会破坏代码。@grey00:intent参数是null
,如图所示。我应该更正我之前的评论,即当没有发出其他启动命令且处于挂起状态时,意图为null
。这是有关System.nanoTime()
的重要信息,很可能是您看到的行为的原因。文件有点误导。中对System.nanoTime()
的描述没有提到它在系统进入深度睡眠时停止,但在的概述部分中描述了该行为。这是有关System.nanoTime()
的重要信息,很可能是您看到的行为的原因。文件有点误导。中的System.nanoTime()
的描述没有提到它在系统进入深度睡眠时停止,但在的概述部分中描述了该行为。