LiveData原理解析和仿写一个LiveDataBus

2024-02-17 17:08

本文主要是介绍LiveData原理解析和仿写一个LiveDataBus,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引入LiveData:

implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"

学习内容:

//这个实际上还是继承了LiveData
public class MutableLiveData<T> extends LiveData<T> {@Overridepublic void postValue(T value) {super.postValue(value);}@Overridepublic void setValue(T value) {super.setValue(value);}
}

开始使用

//初始化
MutableLiveData<String> liveData = new MutableLiveData<>();
//有两种发送值的方式
//第一种
liveData.setValue("123");
//第二种
liveData.postValue("456");

接下来从源码的角度来分析这两个方法的区别。
liveData.postValue

	private final Runnable mPostValueRunnable = new Runnable() {@Overridepublic void run() {Object newValue;synchronized (mDataLock) {newValue = mPendingData;mPendingData = NOT_SET;}//noinspection unchecked//postValue切换到主线程,最终还是调用了setValue()setValue((T) newValue);}};protected void postValue(T value) {boolean postTask;synchronized (mDataLock) {postTask = mPendingData == NOT_SET;mPendingData = value;}if (!postTask) {return;}//可以看到这里我们将赋值的操作切换到主线程,然后再执行。ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);}

所以liveData.postValue可以再任意的线程调用,因为最终会切换到主线程。
liveData.setValue

 @MainThreadprotected void setValue(T value) {//断言的方式判断当前是不是主线程assertMainThread("setValue");//每次设置值的时候都会+1mVersion++;mData = value;//分发更新的值dispatchingValue(null);}

所以liveData.setValue只能再主线程中调用。
然后当我们调用了setValue()之后,接着看dispatchingValue这个方法

public abstract class LiveData<T> {static final int START_VERSION = -1;//观察者的 mapprivate SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =new SafeIterableMap<>();private int mVersion = START_VERSION;
......void dispatchingValue(@Nullable ObserverWrapper initiator) {if (mDispatchingValue) {mDispatchInvalidated = true;return;}mDispatchingValue = true;do {mDispatchInvalidated = false;if (initiator != null) {considerNotify(initiator);initiator = null;} else {//因为initiator = null 所以执行这个方法 遍历每个observerfor (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {//执行这个方法considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue = false;}//最后调用观察者的回调的方法private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.//// we still first check observer.active to keep it as the entrance for events. So even if// the observer moved to an active state, if we've not received that event, we better not// notify for a more predictable notification order.if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}//这个判断非常重要哦//刚开始的时候这两个值都为-1//所以第一次进来就会return//但setValue()执行后,mVersion就+1了,所以就不会return了//这样保证了观察者的回调方法不会因为生命周期的多次回调而调用多次//这个判断也是我们下文仿写LiveDataBus的重要判断条件if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;//noinspection unchecked//调用观察者的回调方法,进行更新的操作。observer.mObserver.onChanged((T) mData);}//生命周期改变时会回调
//GenericLifecycleObserver.onStateChanged方法(是感知到生命周期的重要原因)
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {@NonNullfinal LifecycleOwner mOwner;LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {super(observer);mOwner = owner;}@Overrideboolean shouldBeActive() {return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}//生命周期改变时会回调这个方法@Overridepublic void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {removeObserver(mObserver);return;}//执行父类里的方法activeStateChanged(shouldBeActive());}@Overrideboolean isAttachedTo(LifecycleOwner owner) {return mOwner == owner;}@Overridevoid detachObserver() {mOwner.getLifecycle().removeObserver(this);}}private abstract class ObserverWrapper {final Observer<? super T> mObserver;boolean mActive;int mLastVersion = START_VERSION;ObserverWrapper(Observer<? super T> observer) {mObserver = observer;}abstract boolean shouldBeActive();boolean isAttachedTo(LifecycleOwner owner) {return false;}void detachObserver() {}void activeStateChanged(boolean newActive) {if (newActive == mActive) {return;}// immediately set active state, so we'd never dispatch anything to inactive// ownermActive = newActive;boolean wasInactive = LiveData.this.mActiveCount == 0;LiveData.this.mActiveCount += mActive ? 1 : -1;if (wasInactive && mActive) {onActive();}if (LiveData.this.mActiveCount == 0 && !mActive) {onInactive();}if (mActive) {//分发值 需要更新dispatchingValue(this);}}}
}

到这里观察的回调在哪里调用了,我们就搞清了,我们暂时先不要管onStateChanged再生命周期为什么回调,下文会介绍的不要急。
接下来就是设置观察者了。

liveData.observe(this, new Observer<String>() {@Overridepublic void onChanged(String s) {//在这里处理你自己的逻辑}});

我们就来看这个方法内部是怎么执行的。

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {assertMainThread("observe");//判断当前活动是否被销毁,被销毁直接返回,不注册if (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);if (existing != null && !existing.isAttachedTo(owner)) {throw new IllegalArgumentException("Cannot add the same observer"+ " with different lifecycles");}if (existing != null) {return;}//所以这里就是等于在activity里写如下的代码//AppCompatActivity.getLifecycle().addObserver(wrapper);//这跟之前我们监听activity生周期的方法一样呢//这就是LiveData为什么能感知生命周期的原因owner.getLifecycle().addObserver(wrapper);}

可以看到这个owner,有的小伙会问,欸?为什么是这个形参的类型是LifecycleOwner这是因为我们的AppCompatActivity继承了FragmentActivity继承了ComponentActivity的实现了LifecycleOwner。

public class AppCompatActivity extends FragmentActivity implements AppCompatCallback,TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider {......
}public class FragmentActivity extends ComponentActivity implementsViewModelStoreOwner,ActivityCompat.OnRequestPermissionsResultCallback,ActivityCompat.RequestPermissionsRequestCodeValidator {
}public class ComponentActivity extends Activityimplements LifecycleOwner, KeyEventDispatcher.Component {
}

现在我们再来看一种代码

MutableLiveData<String> liveData = new MutableLiveData<>();
liveData.setValue("123");
liveData.observe(this, new Observer<String>() {@Overridepublic void onChanged(String s) {}
});

这段代码注意 我们是先发送值,然后注册监听者,大家认为我们可以在onChanged回调时接收到“123”吗?答案是肯定的,但这有点不符合常理了,毕竟我们先发送值,但这时候还没有注册事件监听者,后来才注册的事件监听者,也能收到,这就有点奇怪了,我们来看一下LiveData是怎么实现的。

这就要牵扯到下面这段代码了

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {@NonNullfinal LifecycleOwner mOwner;LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {super(observer);mOwner = owner;}@Overrideboolean shouldBeActive() {return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);}@Override//每次生命周期变化都会调用public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {removeObserver(mObserver);return;}//调用父类里的方法activeStateChanged(shouldBeActive());}.....
}
private abstract class ObserverWrapper {final Observer<? super T> mObserver;boolean mActive;int mLastVersion = START_VERSION;.......void activeStateChanged(boolean newActive) {if (newActive == mActive) {return;}// immediately set active state, so we'd never dispatch anything to inactive// ownermActive = newActive;boolean wasInactive = LiveData.this.mActiveCount == 0;LiveData.this.mActiveCount += mActive ? 1 : -1;if (wasInactive && mActive) {onActive();}if (LiveData.this.mActiveCount == 0 && !mActive) {onInactive();}if (mActive) {//调用更新的值分发dispatchingValue(this);}}}.....
}

这段逻辑,相信从上面看到下面的小伙伴都有印象,所以弄清楚onStateChanged为什么在生命周期改变时会被调用。
owner.getLifecycle().addObserver(wrapper);这句话就是我们观察者被注册到监听者的方法。

public class FragmentActivity extends ComponentActivity implementsViewModelStoreOwner,ActivityCompat.OnRequestPermissionsResultCallback,ActivityCompat.RequestPermissionsRequestCodeValidator {.....@Overridepublic Lifecycle getLifecycle() {return super.getLifecycle();}......
}
public class ComponentActivity extends Activityimplements LifecycleOwner, KeyEventDispatcher.Component {private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);@Overridepublic Lifecycle getLifecycle() {return mLifecycleRegistry;}}

所以当我们getLifecycle().addObserver()得到的对象是LifecycleRegistry.addObserver()

	@Overridepublic void addObserver(@NonNull LifecycleObserver observer) {//获取当前activity处在那个生命周期//DESTROYED:0  INITIALIZED:1State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;//下面这两行代码跟LiveData.observe()里的两行代码差不多的ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);if (previous != null) {return;}LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {// it is null we should be destroyed. Fallback quicklyreturn;}boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;State targetState = calculateTargetState(observer);mAddingObserverCounter++;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 recalculatetargetState = calculateTargetState(observer);}if (!isReentrance) {// we do sync only on the top level.//到这了sync();}mAddingObserverCounter--;}private void sync() {LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "+ "new events from it.");return;}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);}Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();if (!mNewEventOccurred && newest != null&& mState.compareTo(newest.getValue().mState) > 0) {forwardPass(lifecycleOwner);}}mNewEventOccurred = false;}private void forwardPass(LifecycleOwner lifecycleOwner) {Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =mObserverMap.iteratorWithAdditions();//从观察者map 迭代所有的观察者while (ascendingIterator.hasNext() && !mNewEventOccurred) {Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred&& mObserverMap.contains(entry.getKey()))) {pushParentState(observer.mState);//然后就调用这个方法observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));popParentState();}}}private void backwardPass(LifecycleOwner lifecycleOwner) {Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =mObserverMap.descendingIterator();while (descendingIterator.hasNext() && !mNewEventOccurred) {Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred&& mObserverMap.contains(entry.getKey()))) {Event event = downEvent(observer.mState);pushParentState(getStateAfter(event));observer.dispatchEvent(lifecycleOwner, event);popParentState();}}}static class ObserverWithState {State mState;GenericLifecycleObserver mLifecycleObserver;ObserverWithState(LifecycleObserver observer, State initialState) {mLifecycleObserver = Lifecycling.getCallback(observer);mState = initialState;}void dispatchEvent(LifecycleOwner owner, Event event) {State newState = getStateAfter(event);mState = min(mState, newState);//然后到这儿就会回调我们在LiveData里的LifecycleBoundObserver的onStateChanged方法mLifecycleObserver.onStateChanged(owner, event);mState = newState;}}

所以sync()方法最终会导致我们的事件回调(记下这个方法名)
然后我们继续

public class ComponentActivity extends Activityimplements LifecycleOwner, KeyEventDispatcher.Component {......@Override@SuppressWarnings("RestrictedApi")protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);//看到这里,我们把自己传了进去ReportFragment.injectIfNeededIn(this);}......
}
public class ReportFragment extends Fragment {private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"+ ".LifecycleDispatcher.report_fragment_tag";public static void injectIfNeededIn(Activity activity) {// ProcessLifecycleOwner should always correctly work and some activities may not extend// FragmentActivity from support lib, so we use framework fragments for activities//这里我们看到我们启动了一个ReportFragmentandroid.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();}}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);dispatchCreate(mProcessListener);dispatch(Lifecycle.Event.ON_CREATE);}@Overridepublic void onStart() {super.onStart();dispatchStart(mProcessListener);dispatch(Lifecycle.Event.ON_START);}@Overridepublic void onResume() {super.onResume();dispatchResume(mProcessListener);dispatch(Lifecycle.Event.ON_RESUME);}private void dispatch(Lifecycle.Event event) {Activity activity = getActivity();if (activity instanceof LifecycleRegistryOwner) {((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);return;}if (activity instanceof LifecycleOwner) {Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();if (lifecycle instanceof LifecycleRegistry) {((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);}}}
.......
}

我们可以看到在ReportFragment的生命周期中都有同一个方法dispatch(),而且最终都会调用getLifecycle().handleLifecycleEvent(event)

 public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {State next = getStateAfter(event);moveToState(next);}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(),上面我们就见过这个方法,所以就可以说通了sync();mHandlingEvent = false;}

正是通过这个handleLifecycleEvent调用了sync然后再调用了dispatchEvent然后调用了mLifecycleObserver.onStateChanged

但是我们LiveData一般都不是用来监听生命周期的,都是用来组件间通信的所以我就来仿照LiveDataBus写一个自己的组件通信,但是我们有的时候不需要粘性事件(未注册的监听者不因该监听到注册前所发送过的事件),所以我们需要自己实现一个可以控制黏性的事件通知者。

//黏性事件
public class MyLiveDataBus {private static MyLiveDataBus instance = new MyLiveDataBus();private Map<String, MyMutableLiveData<Object>> liveDataMap;public static MyLiveDataBus getInstance(){return instance;}private MyLiveDataBus(){liveDataMap = new HashMap<>();}public synchronized<T> MyMutableLiveData<T> with(String key,Class<T> clazz){if(!liveDataMap.containsKey(key)){liveDataMap.put(key,new MyMutableLiveData<Object>());}return (MyMutableLiveData<T>) liveDataMap.get(key);}private static class MyMutableLiveData<T> extends MutableLiveData<T> {private boolean isSticky = false;public void observe(@NonNull LifecycleOwner owner, boolean isSticky , @NonNull Observer<? super T> observer) {this.isSticky = isSticky ;observe(owner,observer);}@Overridepublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {super.observe(owner, observer);try {if(!isSticky ){hook((Observer<T>) observer);}} catch (Exception e) {e.printStackTrace();}}//让mLastVersion和mVersion相等,这样可以在注册监听的时候就不会回调onStateChanged了private void hook(Observer<T> observer) throws Exception {Class<LiveData> liveDataClass = LiveData.class;Field mObserversField = liveDataClass.getDeclaredField("mObservers");mObserversField.setAccessible(true);Object mObservers = mObserversField.get(this);Method get = mObservers.getClass().getDeclaredMethod("get", Object.class);get.setAccessible(true);Object invokeEntry = get.invoke(mObservers, observer);Object observerWrapper = null;if(invokeEntry!=null && invokeEntry instanceof Map.Entry){observerWrapper = ((Map.Entry)invokeEntry).getValue();}if(observerWrapper == null){throw new NullPointerException("ObserverWrapper不能为空");}Class<?> superclass = observerWrapper.getClass().getSuperclass();Field mLastVersionField = superclass.getDeclaredField("mLastVersion");mLastVersionField.setAccessible(true);Field mVersionField = liveDataClass.getDeclaredField("mVersion");mVersionField.setAccessible(true);Object o = mVersionField.get(this);mLastVersionField.set(observerWrapper,o);}}
}

在Activity中

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MutableLiveData<String> liveData = MyLiveDataBus.getInstance().with("key",String.class);liveData.postValue("123");}}public class TwoActivity extends AppCompatActivity {LiveDataBus2.BusMutableLiveData<String> liveData;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);liveData = LiveDataBus2.getInstance().with("code", String.class);liveData.observe(TwoActivity.this,false, new Observer<String>() {@Overridepublic void onChanged(String s) {Log.e("!!!!!!!!",s);}});}}

这样我们就可以实现MainActivity组件和TwoActivity组件之间的通信了,可以不在使用Intent(大小限制)了。

追记:
LiveData当我们继承自Activity就会报错(之前的都是继承了AppCompatActivity)

public class MainActivity extends Activity {
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MyLiveDataBus.MyMutableLiveData<String> liveData = MyLiveDataBus.getInstance().with("key",String.class);//这个observe就会报错 因为继承了ActivityliveData.observe(this, new Observer<String>() {@Overridepublic void onChanged(String s) {}});liveData.setValue("123");}
}

那我们需要怎么修改呢

public class MainActivity extends Activity {LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);@SuppressLint("RestrictedApi")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ReportFragment.injectIfNeededIn(this);MyLiveDataBus.MyMutableLiveData<String> liveData = MyLiveDataBus.getInstance().with("key",String.class);liveData.observe(this, new Observer<String>() {@Overridepublic void onChanged(String s) {}});liveData.setValue("123");}@NonNull@Overridepublic Lifecycle getLifecycle() {return lifecycleRegistry;}}}

这篇关于LiveData原理解析和仿写一个LiveDataBus的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/718454

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu

hdu4059容斥原理

求1-n中与n互质的数的4次方之和 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWrit

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [