当前位置:网站首页>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
边栏推荐
- mysql table 中增加列的SQL语句
- Druid -- JDBC tool class case
- 229. Find mode II
- [paper reading] [3D object detection] voxel transformer for 3D object detection
- What's the difference between error and exception
- A heavy sword without a blade is a great skill
- Leetcode002 -- inverts the numeric portion of a signed integer
- Redis 命令大全
- 数据孤岛是什么?为什么2022年仍然存在数据孤岛?
- QML advanced (V) - realize all kinds of cool special effects through particle simulation system
猜你喜欢
Installation and deployment of Flink and wordcount test
zynq平台交叉编译器的安装
MySQL queries users logged in for at least N consecutive days
Recommended scheme of national manufactured electronic components for intelligent electronic scales
Microbial neuroimmune axis -- the hope of prevention and treatment of cardiovascular diseases
Go reflection rule
test
Coinbase:关于跨链桥的基础知识、事实和统计数据
解决ValueError: Argument must be a dense tensor: 0 - got shape [198602], but wanted [198602, 16].
Flink's important basics
随机推荐
383. Ransom letter
Record the blind injection script
Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.1.15.
New terminal play method: script guidance independent of technology stack
Unity RawImage背景无缝连接移动
Record your own dataset with d435i, run orbslam2 and build a dense point cloud
Fusobacterium -- symbiotic bacteria, opportunistic bacteria, oncobacterium
Mysql, binlog log query
The unity camera rotates with the mouse
Shanghai Hangxin technology sharing 𞓜 overview of safety characteristics of acm32 MCU
leetcode002--将有符号整数的数字部分反转
shell wc (统计字符数量)的基本使用
thymeleaf th:value 为null时报错问题
补充番外14:cmake实践项目笔记(未完待续4/22)
Improving 3D object detection with channel wise transformer
补:注解(Annotation)
Unity摄像头跟随鼠标旋转
The last day of 2021 is the year of harvest.
General enumeration constant class
leetcode009--用二分查找在数组中搜索目标值