代码之家  ›  专栏  ›  技术社区  ›  Cheok Yan Cheng

如何使活动正确地观察生命周期事件

  •  11
  • Cheok Yan Cheng  · 技术社区  · 7 年前

    目前,我需要执行一些操作,当

    • 应用程序已启动。
    • 应用程序已退出。
    • 但不是在活动娱乐,配置改变…

    因此,到目前为止,下面的代码片段非常适合我。我从普通软件中学到了这种把戏- https://commonsware.com/AndroidArch/previews/other-lifecycle-owners https://proandroiddev.com/react-to-app-foreground-and-background-events-with-processlifecycleowner-96278e5816fa

    wenoteapplication.java语言

    public class WeNoteApplication extends Application {
    
        public static class AppLifecycleObserver implements DefaultLifecycleObserver {
            @Override
            public void onResume(LifecycleOwner owner) {
                // Do something when the application launched.
                // But not during activity recreation, configuration change, ...
            }
    
            @Override
            public void onPause(LifecycleOwner owner) {
                // Do something when the application quit.
                // But not during activity recreation, configuration change, ...
            }
        }
    
        private static final AppLifecycleObserver appLifecycleObserver = new AppLifecycleObserver();
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            initLifecycleObserver();
        }
    
        private void initLifecycleObserver() {
            Lifecycle lifecycle = ProcessLifecycleOwner.get().getLifecycle();
            lifecycle.removeObserver(appLifecycleObserver);
            lifecycle.addObserver(appLifecycleObserver);
        }
    }   
    

    但是,我还需要通过使用 Activity , Fragment ,…例如,显示 DialogFragment .

    对于我的入口点主 活动 ,这是我试过的。

    public class MainActivity extends AppCompatActivity implements DefaultLifecycleObserver {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            ProcessLifecycleOwner.get().getLifecycle().removeObserver(this);
            ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    
            setContentView(R.layout.activity_main);
        }
    
        @Override
        public void onResume(LifecycleOwner owner) {
            android.util.Log.i("CHEOK", "onResume LifecycleOwner called");
        }
    
        @Override
        public void onPause(LifecycleOwner owner) {
            android.util.Log.i("CHEOK", "onPause LifecycleOwner called");
        }
    
        @Override
        public void onCreate(LifecycleOwner owner) {
            android.util.Log.i("CHEOK", "onCreate LifecycleOwner called");
        }
    }
    

    由于以下观察结果,它不能按预期工作

    当应用程序启动时

    onCreate LifecycleOwner called
    onResume LifecycleOwner called
    onResume LifecycleOwner called    <-- Why onResume of LifecycleOwner is called twice??
    

    当我转动装置时

    onCreate LifecycleOwner called
    onResume LifecycleOwner called    <-- Why onCreate and onResume of LifecyclOwner is called during configuration change?
    

    使用LiveData重试

    我试着用 LiveData 为了 AppLifecycleObserver 与…沟通 活动 . 但是,在配置更改期间, onResumeLiveData 重新创建的款待 活动 作为新的生命周期所有者。因此,它将再次触发它。

    public class WeNoteApplication extends Application {
    
        public MutableLiveData<LifecycleOwner> onResumeLiveData = new MutableLiveData<>();
    
        public class AppLifecycleObserver implements DefaultLifecycleObserver {
            @Override
            public void onResume(LifecycleOwner owner) {
                // This will only be called during app launch, not configuration change.
                android.util.Log.i("CHEOK", "onResume callback happen in application");
                onResumeLiveData.setValue(owner);
                ...
    
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            WeNoteApplication.instance().onResumeLiveData.observe(this, new Observer<LifecycleOwner>() {
                @Override
                public void onChanged(@Nullable LifecycleOwner lifecycleOwner) {
                    // This will only be called during app launch
                    // This will also be called during configuration change.
                    android.util.Log.i("CHEOK", "onResume callback happen in activity");
                }
            });
    

    所以,我有点困惑。正确的方法是什么? Activitly (或) 碎片 )观察 Lifecycle 事件?也就是说,在配置更改、活动重新创建等过程中,不应触发这些回调事件函数。

    4 回复  |  直到 7 年前
        1
  •  2
  •   Alex aaronmarino    7 年前

    public class SingleLiveEvent<T> extends MutableLiveData<T> {
    
        private static final String TAG = "SingleLiveEvent";
    
        private final AtomicBoolean mPending = new AtomicBoolean(false);
    
        @MainThread
        public void observe(LifecycleOwner owner, final Observer<T> observer) {
    
            if (hasActiveObservers()) {
                Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
            }
    
            // Observe the internal MutableLiveData
            super.observe(owner, new Observer<T>() {
                @Override
                public void onChanged(@Nullable T t) {
                    if (mPending.compareAndSet(true, false)) {
                        observer.onChanged(t);
                    }
                }
            });
        }
    
        @MainThread
        public void setValue(@Nullable T t) {
            mPending.set(true);
            super.setValue(t);
        }
    
        /**
         * Used for cases where T is Void, to make calls cleaner.
         */
        @MainThread
        public void call() {
            setValue(null);
        }
    }
    
        2
  •  1
  •   TpoM6oH    7 年前
        4
  •  0
  •   Keivan Esbati    7 年前

    LifecycleRegistry.addObserver

    Observer LifeCycleRegistery

    @Override
    public void addObserver(@NonNull LifecycleObserver observer) {
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        ...
        State targetState = calculateTargetState(observer);
        while ((statefulObserver.mState.compareTo(targetState) < 0
                && mObserverMap.contains(observer))) {
            pushParentState(statefulObserver.mState);
            statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
            popParentState();
            // mState / subling may have been changed recalculate
            targetState = calculateTargetState(observer);
        }
        ...
    }
    

    observer LifecycleRegistery Activity

    private State calculateTargetState(LifecycleObserver observer) {
            Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);
    
            State siblingState = previous != null ? previous.getValue().mState : null;
            State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
                    : null;
            return min(min(mState, siblingState), parentState);
        }
    

    public class MainActivity extends AppCompatActivity implements DefaultLifecycleObserver {
        ...
    
        @Override
        public void onResume(LifecycleOwner owner) {
            android.util.Log.i("CHEOK", "onResume LifecycleOwner called");
        }
    
        @Override
        public void onPause(LifecycleOwner owner) {
            android.util.Log.i("CHEOK", "onPause LifecycleOwner called");
        }
    
        @Override
        public void onCreate(LifecycleOwner owner) {
            android.util.Log.i("CHEOK", "onCreate LifecycleOwner called");
        }
    }
    

    public class MainActivity extends AppCompatActivity implements DefaultLifecycleObserver {
        ...
    
        @Override
        public void onResume(LifecycleOwner owner) {
            if(owner.getLifecycle().getCurrentState() == Lifecycle.State.RESUMED)
                android.util.Log.i("CHEOK", "onResume LifecycleOwner called");
        }
    
        @Override
        public void onPause(LifecycleOwner owner) {
            if(owner.getLifecycle().getCurrentState() == Lifecycle.State.STARTED)
                android.util.Log.i("CHEOK", "onPause LifecycleOwner called");
        }
    
        @Override
        public void onCreate(LifecycleOwner owner) {
            if(owner.getLifecycle().getCurrentState() == Lifecycle.State.CREATED)
                android.util.Log.i("CHEOK", "onCreate LifecycleOwner called");
        }
    }
    

    ViewModel ApplicationClass LifeCycle.Event

    LiveData