当前位置:网站首页>Jetpack -- lifecycle usage and source code analysis
Jetpack -- lifecycle usage and source code analysis
2022-04-23 04:45:00 【Vivid_ Mm】
Lifecycle What is it? ?
Google Official explanation Lifecycle:
A lifecycle aware component can perform actions in response to another component ( Such as Activity and Fragment) Changes in the life cycle state of .
To put it bluntly, you can monitor Activity/Fragment Life cycle of .
Old life cycle monitoring practices :
class MainActivity : AppCompatActivity() {
private var mainActivityLifeListener : MainActivityLifeListener ?= null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainActivityLifeListener = MainActivityLifeListener();
}
override fun onResume() {
super.onResume()
mainActivityLifeListener?.onResume()
}
override fun onDestroy() {
super.onDestroy()
mainActivityLifeListener?.onDestroy()
}
}
class MainActivityLifeListener {
private val TAG = "MainActivityLifeListener"
fun onResume() = Log.d(TAG,"onResume ...");
fun onDestroy() = Log.d(TAG,"onDestroy ...");
}
The above example code realizes listening MainActivity Life cycle of , But there are the following problems :
1. If you need to listen Activity/Fragment More , You need to call repeatedly MainActivityLifeListener.kt The method in , And it's easy to miss
2. Monitored Activity/Fragment Code redundancy
use Lifecycle Monitor life cycle
Method 1 : Inherit LifecycleObserver Implementation of custom listener
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Inherit LifecycleObserver Implementation of custom listener
lifecycle.addObserver(Myoberver())
}
}
class Myoberver:LifecycleObserver {
private val TAG = "Myoberver"
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connect() = Log.d(TAG,"vivivd Onresume")
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun disconnect() = Log.d(TAG,"vivivd Ondestroy")
}
Method 2 : Inner class inheritance LifecycleObserver
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Inner class Implement monitoring
lifecycle.addObserver(Myoberver())
}
inner class Myoberver:LifecycleObserver{
private val TAG = "Myoberver"
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connect() = Log.d(TAG,"vivivd Onresume")
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun disconnect() = Log.d(TAG,"vivivd Ondestroy")
}
}
Method 3 : Adopt interface inheritance LifecycleObserver
interface IPresenter :LifecycleObserver{
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connect()
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun disconnect()
}
class MyObserver :IPresenter {
private val TAG ="MyObserver"
override fun connect() {
Log.d(TAG, "connect: vivid ")
}
override fun disconnect() {
Log.d(TAG, "disconnect: vivid ")
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Use interface inheritance LifecycleObserver Implement the interface to realize listening
lifecycle.addObserver(MyObserver())
}
}
As can be seen from the example code Lifecycle The observer design pattern is adopted , In a nutshell MyObserver Long eyes staring at MainActivity, as long as MainActivity Changes in the life cycle of MyObserver You can sense .
however MyObserver How to perceive MainActivity Life cycle of ?
Either way , At the end of the day :
lifecycle.addObserver(MyObserver())
problem 1:lifecycle How did you get it ?
problem 2:addObserver What did you do ?
problem 3: How to realize monitoring MainActivity Life cycle ?
MainActivity-->AppCompatActivity-->FragmentActivity-->ComponentActivity
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner,
ActivityResultRegistryOwner,
ActivityResultCaller {
....
}
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
problem 1 answer :
It can be seen that MainActivity Inherited ComponentActivity, and ComponentActivity Realized LifecycleOwner Interface
therefore lifecycle It's from LifecycleOwner Interface getLifecycle Method to get .
problem 2 answer :
addObserver(MyObserver()) perform ( Close your eyes , Only care about observer Where to go )
LifecycleRegistry.java The implementation is as follows :
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
enforceMainThreadIfNeeded("addObserver");
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
......
}
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
// Be careful : The above parameters are Observer It turns into Object
@NonNull
static LifecycleEventObserver lifecycleEventObserver(Object object) {
......
return new ReflectiveGenericLifecycleObserver(object);
}
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}
......
}
Last mInfo Got what we sent in MyObserver Bytecode content of . At this point, you can't continue to view
therefore addObserver Execution will make ReflectiveGenericLifecycleObserver.java In the document mInfo Get our actual bytecode file .
problem 3 answer :
Reopen ComponentActivity.java Medium onCreate()
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
// Restore the Saved State first so that it is available to
// OnContextAvailableListener instances
mSavedStateRegistryController.performRestore(savedInstanceState);
mContextAwareHelper.dispatchOnContextAvailable(this);
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);// reference Glide Realization principle
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
public static void injectIfNeededIn(Activity activity) {
if (Build.VERSION.SDK_INT >= 29) {
// On API 29+, we can register for the correct Lifecycle callbacks directly
LifecycleCallbacks.registerIn(activity);
}
// Prior to API 29 and to maintain compatibility with older versions of
// ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
// need to support activities that don't extend from FragmentActivity from support lib),
// use a framework fragment to get the correct timing of Lifecycle events
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
In fact, in the MainActivity It is covered with a layer of blank ReportFragment, The two are bound , So you can sense MainActivity Life cycle of .
ReportFragment and MainActivity The binding , How did that happen MainActivity Life cycle monitoring ?
Now that the two have been bound , that MainActivity Into the onResume, Again ReportFragment Will also enter onResume
@Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
dispatch(Lifecycle.Event.ON_RESUME);
}
Through the top dispatch Distributed Lidecycle Of ON_RESUME event .
private void dispatch(@NonNull Lifecycle.Event event) {
if (Build.VERSION.SDK_INT < 29) {
// Only dispatch events from ReportFragment on API levels prior
// to API 29. On API 29+, this is handled by the ActivityLifecycleCallbacks
// added in ReportFragment.injectIfNeededIn
dispatch(getActivity(), event);
}
}
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
//SDK > 29
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
//SDK < 29
//activity Namely MainActivity, It chased MainActivity Realized LifecycleOwner
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
enforceMainThreadIfNeeded("handleLifecycleEvent");
moveToState(event.getTargetState()); // Here's the key point
//moveToState The parameters are based on event The event is transformed into the corresponding State
// in other words moveToState Moving is the State
}
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
return;
}
mHandlingEvent = true;
sync();
mHandlingEvent = false;
}
handleLifecycleEvent In the implementation of moveToState But the argument is through Lifecycle.Event Events are transformed ,
As follows :
@NonNull
public State getTargetState() {
switch (this) {
case ON_CREATE:
case ON_STOP:
return State.CREATED;
case ON_START:
case ON_PAUSE:
return State.STARTED;
case ON_RESUME:
return State.RESUMED;
case ON_DESTROY:
return State.DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException(this + " has no target state");
}
Next, let's look at the specific State What are the States
public enum State{
DESTROTED,
INIRIALIZED,
CREATED,
STARTED,
RESUMED;
......
}
There are 6 A life cycle 5 States , First of all Lifecycle.Event Event driven state , After that, the corresponding... Is adjusted by the state Lifecycle.Event
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner); // Key steps
}
Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);// Key steps
}
}
mNewEventOccurred = false;
}
It can be seen that the execution is judged by the enumeration size of the state of the observed person and the current state of the observer backwardPass/forwardPass Method .
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
final Event event = Event.upFrom(observer.mState);// Get the corresponding event through the status
if (event == null) {
throw new IllegalStateException("no event up from " + observer.mState);
}
observer.dispatchEvent(lifecycleOwner, event);// Callback execution event
popParentState();
}
}
}
//LifecycleRegistry.java
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
onStateChanged Finally came back to the question 2 Medium ReflectiveGenericLifecycleObserver.java file
class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
private final Object mWrapped;
private final CallbackInfo mInfo;
ReflectiveGenericLifecycleObserver(Object wrapped) {
mWrapped = wrapped;
mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
mInfo.invokeCallbacks(source, event, mWrapped);
}
}
because mInfo Has been acquired MyObserver.kt Bytecode , Therefore, the corresponding... Is executed through reflection event Notes to events , So as to execute the corresponding MyObserver.kt The method in , That's why MainActivity.kt In the implementation of onResume(),MyObserver.kt Can perceive the corresponding onResume().
版权声明
本文为[Vivid_ Mm]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204220558084045.html
边栏推荐
- Alibaba tip: it is better to create threads manually
- 基于英飞凌MCU GTM模块的无刷电机驱动方案开源啦
- leetcode005--原地删除数组中的重复元素
- 使用model.load_state_dict()时,出现AttributeError: ‘str‘ object has no attribute ‘copy‘
- MySQL - data read / write separation, multi instance
- [pytoch foundation] torch Split() usage
- Better way to read configuration files than properties
- Gets all dates between two times
- Key points of AWS eks deployment and differences between console and eksctl creation
- shell wc (统计字符数量)的基本使用
猜你喜欢

Installation and deployment of Flink and wordcount test

Small volume Schottky diode compatible with nsr20f30nxt5g

zynq平台交叉编译器的安装

2021数学建模国赛一等奖经验总结与分享

Flink's important basics

QML进阶(五)-通过粒子模拟系统实现各种炫酷的特效

Go reflection rule

C language: Advanced pointer

Spark FAQ sorting - must see before interview

使用model.load_state_dict()时,出现AttributeError: ‘str‘ object has no attribute ‘copy‘
随机推荐
Basic use of shell WC (counting the number of characters)
selenium模式下切换窗口,抓取数据的实现
The object needs to add additional attributes. There is no need to add attributes in the entity. The required information is returned
Installation du compilateur croisé de la plateforme zynq
Create VPC in AWS console (no plate)
Unity攝像頭跟隨鼠標旋轉
Logger and zap log Library in go language
程序员抱怨:1万2的工资我真的活不下去了,网友:我3千咋说
阿里十年技术专家联合打造“最新”Jetpack Compose项目实战演练(附Demo)
補:注解(Annotation)
L2-011 玩转二叉树(建树+BFS)
基于英飞凌MCU GTM模块的无刷电机驱动方案开源啦
New terminal play method: script guidance independent of technology stack
zynq平台交叉编译器的安装
Unity3d practical skills - theoretical knowledge base (I)
Coinbase: basic knowledge, facts and statistics about cross chain bridge
leetcode002--将有符号整数的数字部分反转
Redis 命令大全
重剑无锋,大巧不工
List&lt; Map&gt; Replication: light copy and deep copy