每次打开/关闭应用程序时,无论是从任务抽屉启动还是从任务抽屉启动,我都希望在服务器上签入和签出用户。有没有办法做到这一点,同时避免在每个活动中调用一个函数?
谢谢!
答案 0 :(得分:9)
修改强>
在this answer中,matdev提醒我注意通过ProcessLifeCycleOwner
收听应用生命周期事件的更现代的方法。见https://developer.android.com/topic/libraries/architecture/lifecycle
因此,为了更好地组织所需的会话管理功能,应使用以下结构。在SessionTracker
的{{1}}中注册onCreate
。然后将与跟踪用户会话相关的功能隔离到MyApplication
类。
首先添加到build.gradle
SessionTracker
然后,实施以下内容:
dependencies {
implementation "android.arch.lifecycle:extensions:1.1.1"
}
以前的答案
d60402 here提供的答案以及Hanno Binder使用 Application.registerActivityLifecycleCallbacks()注册活动回调的建议使我得到了这个解决方案。
我将应用程序和已注册的回调扩展到Activity方法onPause和onStart,如下所示。在这些方法中,启动/停止计时器(一个活动被退出,其中调用onPause,在调用onStart时输入一个新活动)。旗帜" wasInBackground"当应用确定在后台/前景(真/假)时切换。如果在运行onStart回调时应用程序处于后台," appEntered"叫做。如果onPause和onStart回调之间传递的时间大于指定的时间(给活动转换留出足够的时间)" appExited"调用app会话的地方被调用。
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(SessionTracker.getInstance());
}
}
public class SessionTracker implements LifecycleObserver {
private static SessionTracker sSessionTracker;
private static final long MAX_ACTIVITY_TRANSITION_TIME_MS = 2000; // Time allowed for transitions
private Timer mStopDelayTimer;
private TimerTask mActivityTransitionTimerTask;
private boolean mWasInBackground = true;
private AppSession mAppSession;
public static SessionTracker getInstance() {
if (sSessionTracker == null) {
sSessionTracker = new SessionTracker();
}
return sSessionTracker;
}
private SessionTracker() {
// no-op
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onLifecycleStop() {
submitAppSession(appSession);
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onLifecycleStart() {
mAppSession = new AppSession();
}
private void submitAppSession(AppSession appSession) {
// TODO submit app session here
}
}
public class AppSession {
/* TODO */
}
答案 1 :(得分:6)
您可以查看Application.registerActivityLifecycleCallbacks()
& c。
答案 2 :(得分:1)
好。我发布我的评论作为答案,因为提出问题的原始用户发现这确实很有用。
上述答案的问题在于,该应用程序并不想检查和解决问题。在活动关闭时结帐,而是在应用程序启动或恢复时结帐。因此,当您在应用程序打开时关闭或在活动之间移动时,这可能会出现问题,这仍然会调用oncreate()和onpause()函数。
此问题也在之前的stackoverflow上进行了讨论。以下是链接。
How to detect when an Android app goes to the background and come back to the foreground
解决此问题可能有不同的方法。以上链接提供了有关如何解决问题的更多信息。
答案 3 :(得分:1)
android.arch.lifecycle 包提供了类和接口,可让您知道应用程序在后台还是前台运行。
您的应用程序应实现LifecycleObserver接口:
public class MyApplication extends Application implements LifecycleObserver {
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onAppBackgrounded() {
Log.d("MyApp", "App in background");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onAppForegrounded() {
Log.d("MyApp", "App in foreground");
}
}
为此,您需要将此依赖项添加到build.gradle文件中:
dependencies {
implementation "android.arch.lifecycle:extensions:1.1.1"
}
按照Google的建议,您应尽量减少在活动的生命周期方法中执行的代码:
一个常见的模式是实施依赖者的行为 活动和片段的生命周期方法中的组件。 但是,这种模式导致代码的组织不善,并导致 错误的扩散。通过使用生命周期感知的组件,您可以 可以将依赖组件的代码移出生命周期方法 以及组件本身。
您可以在此处了解更多信息: https://developer.android.com/topic/libraries/architecture/lifecycle
答案 4 :(得分:0)
您可以使用oncreate()
和onpause()
方法。