Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/203.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我的服务在手机关机时表现得很奇怪_Java_Android_Service_Timer - Fatal编程技术网

Java 我的服务在手机关机时表现得很奇怪

Java 我的服务在手机关机时表现得很奇怪,java,android,service,timer,Java,Android,Service,Timer,这项服务的目的是跟踪按钮按下后的时间。如果显示menuactivity,它会使用计时器每分钟更新menuactivity上的一些值,否则,它只会更新自身 当应用程序打开或关闭时,它似乎可以正常工作,但当手机关闭时,它的速度会降低到不到应有速度的一半(实际21分钟过去后仅显示10分钟过去了) 如果我关机一段时间后又回到menuactivity,它在几个周期后不会“自行修复”。我认为onStartCommand可能会被多次调用,但唯一可能启动服务的时间是按下按钮时 但该服务唯一可能启动的时间是 按钮

这项服务的目的是跟踪按钮按下后的时间。如果显示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()
的描述没有提到它在系统进入深度睡眠时停止,但在的概述部分中描述了该行为。