[问答记录]三方技术组件:谷歌 Jetpack LifeCycle

294 阅读3分钟

Q1:lifecycle 使用方式以及要解决的问题

LifeCycle 对外提供感知生命周期的能力,内部采用:“观察者模式”来实现。工作原理在框架层中实现,采用注入 HolderFragment 作为主题对象。其作用有两个方面:

  • 感知生命周期状态以及Event --> State 状态转换.
  • 分发 Event 给观察者。

初始化

public class LifeCycleDemoFragment extends Fragment {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_CREATE) {
                    Log.d("hlwang", "生命周期 onCreate....");
                } else if (event == Lifecycle.Event.ON_RESUME) {
                    Log.d("hlwang", "生命周期 onResume....");
                } else if (event == Lifecycle.Event.ON_START) {
                    Log.d("hlwang", "生命周期 onStart....");
                } else if (event == Lifecycle.Event.ON_PAUSE) {
                    Log.d("hlwang", "生命周期 onPause....");
                } else if (event == Lifecycle.Event.ON_STOP) {
                    Log.d("hlwang", "生命周期 onStop....");
                } else if (event == Lifecycle.Event.ON_DESTROY) {
                    Log.d("hlwang", "生命周期 onDestory....");
                }
            }
        });
    }
}

作用

LifeCycle 提供了外部组件感知 Android Activity/Fragemnt生命周期的能力。松耦合的设计,提供了对象间一对多的依赖,当生命周期对象状态发生改变时,它的所有观察者都能收到通知并作出更新。

附:谷歌官方文档

应用场景

  • 判断应用是在前台还是在后台
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {// 页面在前台

} else {// 页面在后台

}
  • 根据声明周期来做一些释放资源的操作。
    • Handler 在 onDestory 中,移除不再使用的资源,避免内存泄漏MemoryLeak
    • 可参考:AutoDisponse + RxLifeCycle
    • Jetpack Lifecycle + LiveData 是级联的观察者

Q2:在不同的生命周期方法中,添加观察者,有什么需要额外注意的吗?

A2:在任何生命周期都可以通过getLifecycle().addObserver来添加观察者对象。但回调次数不一样。

如果在 onPause 中注册观察者,观察者的onStateChanged会执行多次!!!

即:

  • 1、onPause的生命周期 Event,会被解析成:STARTED 的State。
  • 2、当getLifecycle().addObserver时,初始State = INITIALIZED
  • 3、从 INITIALIZED --> CREATED --> STARTED,onStateChanged会收到多次回调,从onCreate到onStop。
01-17 22:26:12.353 D/hlwang  (12536): onPause ---> 生命周期 onCreate....
01-17 22:26:12.359 D/hlwang  (12536): onPause ---> 生命周期 onStart....
01-17 22:26:12.930 D/hlwang  (12536): onPause ---> 生命周期 onStop....
01-17 22:26:12.972 D/hlwang  (12536): onPause ---> 生命周期 onDestory....

Q3:实现原理以及场景扩展

3.1、Activity

在 Activity 继承树中的ComponentActivity,ROM 源代码中应该是在 SupportActivity 中。在 onCreate 生命周期中,

path:androidx.activity.ComponentActivity
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ViewModelStoreOwner,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner {

    /**
     * {@inheritDoc}
     *
     * If your ComponentActivity is annotated with {@link ContentView}, this will
     * call {@link #setContentView(int)} for you.
     */
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSavedStateRegistryController.performRestore(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
        if (mContentLayoutId != 0) {
            setContentView(mContentLayoutId);
        }
    }

}

3.2、Fragment

在 Fragment 实现类中,生命周期方法中,会看到类似这样的实现:

3.3、其他场景,例如:Application

如果,用户的客户端版本低,且迁移到androidx以及其他高版本成本较大,在这种情况下,也想使用 Lifecycle,那么,可以使用如下方式:

path:androidx.lifecycle.ProcessLifecycleOwner
public class ProcessLifecycleOwner implements LifecycleOwner {
    ActivityInitializationListener mInitializationListener =
            new ActivityInitializationListener() {
                @Override
                public void onCreate() {
                }

                @Override
                public void onStart() {
                    activityStarted();
                }

                @Override
                public void onResume() {
                    activityResumed();
                }
            };

    void attach(Context context) {
        mHandler = new Handler();
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        Application app = (Application) context.getApplicationContext();
        app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                ReportFragment.get(activity).setProcessListener(mInitializationListener);
            }

            @Override
            public void onActivityPaused(Activity activity) {
                activityPaused();
            }

            @Override
            public void onActivityStopped(Activity activity) {
                activityStopped();
            }
        });
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mRegistry;
    }

    void activityStarted() {
        mStartedCounter++;
        if (mStartedCounter == 1 && mStopSent) {
            mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
            mStopSent = false;
        }
    }

    void activityResumed() {
        mResumedCounter++;
        if (mResumedCounter == 1) {
            if (mPauseSent) {
                mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
                mPauseSent = false;
            } else {
                mHandler.removeCallbacks(mDelayedPauseRunnable);
            }
        }
    }

    // ...
}