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


当前回答

你可以使用:

onRestart ()

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

其他回答

这里有一个解决方案,通过使用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")

基于Martín marconcini的回答(谢谢!)我终于找到了一个可靠(而且非常简单)的解决方案。

public class ApplicationLifecycleHandler implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

    private static final String TAG = ApplicationLifecycleHandler.class.getSimpleName();
    private static boolean isInBackground = false;

    @Override
    public void onActivityCreated(Activity activity, Bundle bundle) {
    }

    @Override
    public void onActivityStarted(Activity activity) {
    }

    @Override
    public void onActivityResumed(Activity activity) {

        if(isInBackground){
            Log.d(TAG, "app went to foreground");
            isInBackground = false;
        }
    }

    @Override
    public void onActivityPaused(Activity activity) {
    }

    @Override
    public void onActivityStopped(Activity activity) {
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
    }

    @Override
    public void onConfigurationChanged(Configuration configuration) {
    }

    @Override
    public void onLowMemory() {
    }

    @Override
    public void onTrimMemory(int i) {
        if(i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){
            Log.d(TAG, "app went to background");
            isInBackground = true;
        }
    }
}

然后将其添加到Application类的onCreate()中

public class MyApp extends android.app.Application {

    @Override
    public void onCreate() {
        super.onCreate();

        ApplicationLifeCycleHandler handler = new ApplicationLifeCycleHandler();
        registerActivityLifecycleCallbacks(handler);
        registerComponentCallbacks(handler);

    }

}

我在Github app- prospect -background-listen上创建了一个项目

为应用程序中的所有Activity创建一个BaseActivity。

public class BaseActivity extends Activity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    public static boolean isAppInFg = false;
    public static boolean isScrInFg = false;
    public static boolean isChangeScrFg = false;

    @Override
    protected void onStart() {
        if (!isAppInFg) {
            isAppInFg = true;
            isChangeScrFg = false;
            onAppStart();
        }
        else {
            isChangeScrFg = true;
        }
        isScrInFg = true;

        super.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();

        if (!isScrInFg || !isChangeScrFg) {
            isAppInFg = false;
            onAppPause();
        }
        isScrInFg = false;
    }

    public void onAppStart() {

        // Remove this toast
        Toast.makeText(getApplicationContext(), "App in foreground",    Toast.LENGTH_LONG).show();

        // Your code
    }

    public void onAppPause() {

        // Remove this toast
        Toast.makeText(getApplicationContext(), "App in background",  Toast.LENGTH_LONG).show();

        // Your code
    }
}

现在使用这个BaseActivity作为一个超类的所有你的活动像MainActivity扩展BaseActivity和onAppStart将被调用时,你启动你的应用程序和onappause()将被调用时,应用程序从后台从任何屏幕。

您可以在ActivityLifecycleCallbacks和ComponentCallbacks2的帮助下轻松实现这一点。

创建一个实现上述接口的类AppLifeCycleHandler。

package com.sample.app;

import android.app.Activity;
import android.app.Application;
import android.content.ComponentCallbacks2;
import android.content.res.Configuration;
import android.os.Bundle;

/**
 * Created by Naveen on 17/04/18
 */
public class AppLifeCycleHandler
    implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {

  AppLifeCycleCallback appLifeCycleCallback;

  boolean appInForeground;

  public AppLifeCycleHandler(AppLifeCycleCallback appLifeCycleCallback) {
    this.appLifeCycleCallback = appLifeCycleCallback;
  }

  @Override
  public void onActivityResumed(Activity activity) {
    if (!appInForeground) {
      appInForeground = true;
      appLifeCycleCallback.onAppForeground();
    }
  }

  @Override
  public void onTrimMemory(int i) {
    if (i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
      appInForeground = false;
      appLifeCycleCallback.onAppBackground();
    }
  }

  @Override
  public void onActivityCreated(Activity activity, Bundle bundle) {

  }

  @Override
  public void onActivityStarted(Activity activity) {

  }

  @Override
  public void onActivityPaused(Activity activity) {

  }

  @Override
  public void onActivityStopped(Activity activity) {

  }

  @Override
  public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

  }

  @Override
  public void onActivityDestroyed(Activity activity) {

  }

  @Override
  public void onConfigurationChanged(Configuration configuration) {

  }

  @Override
  public void onLowMemory() {

  }

  interface AppLifeCycleCallback {

    void onAppBackground();

    void onAppForeground();
  }
}

在你的类中,当应用程序在前台和后台之间切换时,应用程序实现AppLifeCycleCallback来获得回调。如下图所示。

public class BaseApplication extends Application implements AppLifeCycleHandler.AppLifeCycleCallback{

    @Override
    public void onCreate() {
        super.onCreate();
        AppLifeCycleHandler appLifeCycleHandler = new AppLifeCycleHandler(this);
        registerActivityLifecycleCallbacks(appLifeCycleHandler);
        registerComponentCallbacks(appLifeCycleHandler);
    }

    @Override
    public void onAppBackground() {
        Log.d("LifecycleEvent", "onAppBackground");
    }

    @Override
    public void onAppForeground() {
        Log.d("LifecycleEvent", "onAppForeground");
    }
}

希望这能有所帮助。

编辑 作为替代方案,您现在可以使用生命周期感知的体系结构组件。

ActivityLifecycleCallbacks可能很有趣,但是没有很好的文档。

但是,如果您调用registerActivityLifecycleCallbacks(),您应该能够在活动被创建、销毁等时获得回调。您可以为活动调用getComponentName()。