我试图写一个应用程序,做一些具体的时候,它被带回前台后一段时间。是否有一种方法可以检测应用程序是被发送到后台还是被带到前台?


当前回答

这是我的解决方案https://github.com/doridori/AndroidUtils/blob/master/App/src/main/java/com/doridori/lib/app/ActivityCounter.java

基本上涉及到用计时器计算所有Activity的生命周期方法,以捕捉当前前台没有活动但应用程序(即在旋转)的情况

其他回答

你可以使用:

onRestart ()

重新开始和重新开始的区别。

您可以在应用程序类中简单地调用此方法

ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
                Log.e(TAG, "onStateChanged: " + event.toString());
            }
        });

生命周期。事件将返回应用程序的状态

ON_CREATE
ON_START
ON_RESUME
ON_PAUSE
ON_STOP
ON_DESTROY
ON_ANY

当应用程序进入后台时,它将返回ON_PAUSE & ON_STOP 当应用程序进入前台时,将返回ON_START & ON_RESUME

这里有一个解决方案,通过使用deboning逻辑,确保我们不会得到连续的背景/前景事件。所以,它总是反映一种稳定的背景/前景状态。

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import java.util.Timer
import java.util.TimerTask

/**
 * An observer class to listen on the app's lifecycle.
 */
class AppLifecycleObserver(
    private val onAppGoesToBackground: () -> Unit = {},
    private val onAppEntersForeground: () -> Unit = {}
) : LifecycleEventObserver {

    private val debounce = DebouncingTimer(timeout = 10)

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        debounce.refresh {
            when (event.targetState) {
                Lifecycle.State.CREATED -> onAppGoesToBackground()
                Lifecycle.State.RESUMED -> onAppEntersForeground()
                else -> Unit
            }
        }
    }

    fun attach() {
        ProcessLifecycleOwner.get().lifecycle.addObserver(this)
    }

    fun detach() {
        ProcessLifecycleOwner.get().lifecycle.removeObserver(this)
    }

    private class DebouncingTimer(private val timeout: Long) {

        private var timer: Timer? = null

        fun refresh(job: () -> Unit) {
            timer?.cancel()
            timer = Timer()
            timer?.schedule(object : TimerTask() {
                override fun run() = job.invoke()
            }, timeout)
        }
    }
}

只需要创建一个AppLifecycleObserver实例:

private val appLifecycleObserver = AppLifecycleObserver(
        onAppGoesToBackground = { // do whatever... },
        onAppEntersForeground = { // do whatever... }
    )
// Attach the observer when it is needed:
appLifecycleObserver.attach()

// Remove when there is no need to it:
appLifecycleObserver.detach()

不要忘记添加一个合适的依赖版本:

implementation("androidx.lifecycle:lifecycle-process:$lifecycle_version")

这是@d60402回答的修改版本:https://stackoverflow.com/a/15573121/4747587

按照上面提到的去做。但是,与其有一个Base Activity,并将其作为每个活动的父活动,并重写onResume()和onPause,不如执行以下操作:

在你的应用程序类中,添加这样一行:

registerActivityLifecycleCallbacks(应用程序。ActivityLifecycleCallbacks回调);

这个回调有所有的活动生命周期方法,你现在可以覆盖onactivityresume()和onActivityPaused()。

看看这个Gist: https://gist.github.com/thsaravana/1fa576b6af9fc8fff20acfb2ac79fa1b

我们用这个方法。它看起来太简单了,但它在我们的应用程序中经过了良好的测试,实际上在所有情况下都运行得非常好,包括通过“home”按钮进入主屏幕,通过“返回”按钮,或在屏幕锁定后返回主屏幕。试一试。

想法是,当在前景,Android总是开始新的活动之前停止前一个。这并不能保证,但这就是它的工作原理。顺便说一句,Flurry似乎使用了同样的逻辑(只是猜测,我没有检查,但它在相同的事件中挂钩)。

public abstract class BaseActivity extends Activity {

    private static int sessionDepth = 0;

    @Override
    protected void onStart() {
        super.onStart();       
        sessionDepth++;
        if(sessionDepth == 1){
        //app came to foreground;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (sessionDepth > 0)
            sessionDepth--;
        if (sessionDepth == 0) {
            // app went to background
        }
    }

}

编辑:根据注释,我们也移动到onStart()在以后的版本的代码。此外,我还添加了超级调用,这是我最初的文章中所没有的,因为这更像是一个概念,而不是一个工作代码。