所谓后台,我的意思是应用程序的活动目前对用户都不可见?


当前回答

简单直接的回答:

override fun onPause() {
    Log.i("APP LIFECYCLE", "App Enter BACKground")
    isForeground = false
    super.onPause()
}

override fun onResume() {
    Log.i("APP LIFECYCLE", "App Enter FOREground")
    isForeground = true
    super.onResume()
}

然后只需使用您的活动的isForeground属性来检查状态。

其他回答

Idolon的答案是容易出错的,更复杂的,尽管在这里重复检查android应用程序是在前台或不是?从后台任务或服务中确定当前的前台应用程序

有一个更简单的方法:

在所有活动扩展的BaseActivity上:

protected static boolean isVisible = false;

 @Override
 public void onResume()
 {
     super.onResume();
     setVisible(true);
 }


 @Override
 public void onPause()
 {
     super.onPause();
     setVisible(false);
 }

无论何时你需要检查你的应用程序活动是否在前台,只需检查isVisible();

要理解这种方法,请检查side-by-side活动生命周期的答案:activity side-by-side生命周期

这篇旧文章的另一个解决方案(对那些可能有帮助的人来说):


<application android:name=".BaseApplication" ... >

public class BaseApplication extends Application {

    private class Status {
        public boolean isVisible = true;
        public boolean isFocused = true;
    }

    private Map<Activity, Status> activities;

    @Override
    public void onCreate() {
        activities = new HashMap<Activity, Status>();
        super.onCreate();
    }

    private boolean hasVisibleActivity() {
        for (Status status : activities.values())
            if (status.isVisible)
                return true;
        return false;
    }

    private boolean hasFocusedActivity() {
        for (Status status : activities.values())
            if (status.isFocused)
                return true;
        return false;
    }

    public void onActivityCreate(Activity activity, boolean isStarting) {
        if (isStarting && activities.isEmpty())
            onApplicationStart();
        activities.put(activity, new Status());
    }

    public void onActivityStart(Activity activity) {
        if (!hasVisibleActivity() && !hasFocusedActivity())
            onApplicationForeground();
        activities.get(activity).isVisible = true;
    }

    public void onActivityWindowFocusChanged(Activity activity, boolean hasFocus) {
        activities.get(activity).isFocused = hasFocus;
    }

    public void onActivityStop(Activity activity, boolean isFinishing) {
        activities.get(activity).isVisible = false;
        if (!isFinishing && !hasVisibleActivity() && !hasFocusedActivity())
            onApplicationBackground();
    }

    public void onActivityDestroy(Activity activity, boolean isFinishing) {
        activities.remove(activity);
        if(isFinishing && activities.isEmpty())
            onApplicationStop();
    }

    private void onApplicationStart() {Log.i(null, "Start");}
    private void onApplicationBackground() {Log.i(null, "Background");}
    private void onApplicationForeground() {Log.i(null, "Foreground");}
    private void onApplicationStop() {Log.i(null, "Stop");}

}

public class MyActivity extends BaseActivity {...}

public class BaseActivity extends Activity {

    private BaseApplication application;

    @Override
    protected void onCreate(Bundle state) {
        application = (BaseApplication) getApplication();
        application.onActivityCreate(this, state == null);
        super.onCreate(state);
    }

    @Override
    protected void onStart() {
        application.onActivityStart(this);
        super.onStart();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        application.onActivityWindowFocusChanged(this, hasFocus);
        super.onWindowFocusChanged(hasFocus);
    }

    @Override
    protected void onStop() {
        application.onActivityStop(this, isFinishing());
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        application.onActivityDestroy(this, isFinishing());
        super.onDestroy();
    }

}

谷歌解决方案-不是一个黑客,像以前的解决方案。使用ProcessLifecycleOwnerKotlin:

class ArchLifecycleApp : Application(), LifecycleObserver {

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(this)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onAppBackgrounded() {
        //App in background
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onAppForegrounded() {
        // App in foreground
    }

}

Java:

public class ArchLifecycleApp extends Application implements LifecycleObserver {

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onAppBackgrounded() {
        //App in background
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onAppForegrounded() {
        // App in foreground
    }
}

在app.gradle

dependencies {
    ...
    implementation "android.arch.lifecycle:extensions:1.1.0"

    //New Android X dependency is this - 
    implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
    
}

allprojects {
    repositories {
        ...
        google()
        jcenter()
        maven { url 'https://maven.google.com' }
    }
}

你可以在这里阅读更多关于生命周期相关的体系结构组件——https://developer.android.com/topic/libraries/architecture/lifecycle

我想出的最好的解决办法是使用计时器。

你已经在onPause()中启动了一个定时器,并在onResume()中取消了相同的定时器,有一个定时器的实例(通常在应用程序类中定义)。计时器本身被设置为在2秒后(或您认为合适的任何时间间隔)运行Runnable,当计时器触发时,您设置一个标志,将应用程序标记为在后台。

在取消定时器之前的onResume()方法中,您可以查询后台标志来执行任何启动操作(例如开始下载或启用位置服务)。

这个解决方案允许您在back堆栈上有几个活动,并且不需要任何权限来实现。

如果你也使用事件总线,这个解决方案也很有效,因为你的计时器可以简单地触发一个事件,应用程序的各个部分可以相应地做出响应。

除非你自己跟踪它,否则无法确定你的任何活动是否可见。也许你应该考虑问一个新的StackOverflow问题,解释一下你想从用户体验中获得什么,这样我们也许可以给你其他的实现想法。