我们平时都是用的Activity或者Fragment封装好的。对应的也就是在activity或者fragment的生命周期里监听。
getLifecycle().addObserver();
如果我们要全局监听app的状态,app在前台还是后台,以前用的就是application的如下方法,计算在前台的activity的数量来判断
app.registerActivityLifecycleCallbacks
实际上系统已经为我们封装好了类似的东西了。
ProcessLifecycleOwner
public class ProcessLifecycleOwner implements LifecycleOwner {
@VisibleForTesting
static final long TIMEOUT_MS = 700; //mls
先看下如何使用,单例模式,放心使用
ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
System.out.println("state change==="+event);
}
});
看下这个类的注解
You can consider this LifecycleOwner as the composite of all of your Activities, except that Lifecycle.Event.ON_CREATE will be dispatched once and Lifecycle.Event.ON_DESTROY will never be dispatched
oncreate只会发送一次,ondestory不会发送,看下图,进入app之后切入后台再切回前台来回切换的state
源码分析
单列模式
private static final ProcessLifecycleOwner sInstance = new ProcessLifecycleOwner();
/**
* The LifecycleOwner for the whole application process. Note that if your application
* has multiple processes, this provider does not know about other processes.
*
* @return {@link LifecycleOwner} for the whole application.
*/
@NonNull
public static LifecycleOwner get() {
return sInstance;
}
static void init(Context context) {
sInstance.attach(context);
}
init方法是通过ContentProvider来初始化的
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
看下attach(context)里做啥了,就是registerActivityLifecycleCallbacks来监听activity的状态变化了
void attach(Context context) {
mHandler = new Handler();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
Application app = (Application) context.getApplicationContext();
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
我们来看下监听到activity变化以后咋处理的,这里就看下resume和pause就行了,
里边是延迟700ms判断resume个数的,从0到1才会发送resume状态,从1到0才会发送pause状态
void activityResumed() {
mResumedCounter++;
if (mResumedCounter == 1) {
if (mPauseSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
mPauseSent = false;
} else {
mHandler.removeCallbacks(mDelayedPauseRunnable);
}
}
}
void activityPaused() {
mResumedCounter--;
if (mResumedCounter == 0) {
mHandler.postDelayed(mDelayedPauseRunnable, TIMEOUT_MS);
}
}
end...