java - 当电话关闭时,我的服务表现异常

标签 java android service timer

该服务的目的是跟踪按下按钮后的时间。如果菜单 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/

相关文章:

Java - 迭代 HashMap 替换 ArrayList

java - Android 中无需本地化的多语言功能,但可通过按钮实现

android - 如何以编程方式将 autoSizeTextType 统一?

java - 新项目 (OS X) 上的 Android Studio Gradle 错误

service - 使用 sc create 将带有额外参数的 .exe 作为 Windows 服务运行

java - Spring boot应用程序延迟加载环境变量作为init.d服务

android - 如何防止应用程序崩溃时服务被关闭-android

java - 无法在build.gradle中初始化flyway {}

java - Apache Tomcat 上下文属性或上下文变量的参数化值?

java - 在 ou=users 中通过 cn 搜索用户,ou=ldap 中的系统目录