无缝交换活动和服务并返回

时间:2012-02-25 17:24:19

标签: android

我希望在我的活动被置于后台(按下主页按钮,或者活动以任何其他方式中断)后启动服务,并在我的活动回到前台后停止服务。

在任何Activity生命周期回调中放置服务的开始和停止(例如从onPause开始,然后停在onResume中)并不是很好,因为它们也会在方向更改时调用,而且我不会我想启动服务并立即停止服务。

此外,我不想一直在后台运行服务,但只有在活动不可见时才会运行。

此用例的最佳做法是什么?

2 个答案:

答案 0 :(得分:1)

onPause和onResume仍然是最好的做法。如果您担心方向更改等短期事件,请在onPause中设置计时器...当计时器到期时,启动服务,并取消onResume中的计时器。

答案 1 :(得分:0)

我并没有真正回答我自己的问题,而是在这里记录了我已经完成的研究,以及为什么我认为计时器是一个更好的解决方案(因此我接受了mah的建议)。 希望这会帮助其他人试图解决这个问题,也可能有助于解决不同的问题。

我的想法是使用Application类捕获配置更改,添加时间戳(如果已更改),并检查onPause()是否有配置更改 - 如果有 - 不要启动服务。< / p>

由于两个原因,它没有成功:

  1. 在onConfigurationChange()和onPause()之间花了相当长的时间 - 大约500ms。 (在Galaxy S上测试过),所以我需要使用一个很长的门槛。
  2. 具有较长的阈值,用户很可能在配置更改(方向,键盘拉动等)后立即点击主页按钮。因此,应用程序将在没有服务启动的情况下退出,这是不可接受的。
  3. 供参考,这是代码:

    public class RealPauseApp extends Application {
    
        Configuration oldConfig = null;
        private long configChangedAt;
        private static final int CONFIG_TIME_THRESHOLD = 1000;
    
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            if (oldConfig != null) {
                Log.v("#",
                        "onConfigurationChanged: " + newConfig.diff(oldConfig));
                if (newConfig.diff(oldConfig) > 0) {
                    configChangedAt = System.currentTimeMillis();
                }
            } else {
                Log.v("#", "oldConfig is null");
            }
            oldConfig = newConfig;
    
        }
    
        public boolean didConfigJustChanged() {
            if (System.currentTimeMillis() - configChangedAt < CONFIG_TIME_THRESHOLD) {
                return true;
            }
            return false;
        }
    
    
    }
    

    以及活动中的相关部分:

    @Override
    protected void onResume() {
        super.onResume();
        Log.v("++++", "onResume: ** will stop any service here **");
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        if (!((RealPauseApp) getApplication()).didConfigJustChanged()) {
            // NO CONFIG CHANGE - It means that we're really pausing
            Log.v("----", "onPause: ** will start the service here **");
        } else {
            // CONFIG CHANGED - No need to start service
    
            // * POSSIBLE FALSE NEGATIVE * - if config was indeed changed
            // and just after that the activity was really paused
        }
    }
    

    所以这对我的问题不是一个好的解决方案 - 但仍然是一个有用的实验。 它可能与某人有关,作为参考。