在调用 getLifecycle().addObserver()
的时候报出这样的错误java
java.lang.IllegalArgumentException at androidx.lifecycle.LifecycleRegistry.upEvent(SourceFile:279) at androidx.lifecycle.LifecycleRegistry.forwardPass(SourceFile:293) at androidx.lifecycle.LifecycleRegistry.sync(SourceFile:333) at androidx.lifecycle.LifecycleRegistry.addObserver(SourceFile:189)
问题代码出如今这里 LifecycleRegisty
这个类中,代码以下android
private static Event upEvent(State state) { switch (state) { case INITIALIZED: case DESTROYED: return ON_CREATE; case CREATED: return ON_START; case STARTED: return ON_RESUME; case RESUMED: throw new IllegalArgumentException(); } throw new IllegalArgumentException("Unexpected state value " + state); }
当传入的状态是 RESUMED
的时候能够就会抛出错误,而调用这个方法的代码以下bash
@Override public void addObserver(LifecycleObserver observer) { State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver); if (previous != null) { return; } boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent; State targetState = calculateTargetState(observer); mAddingObserverCounter++; while ((statefulObserver.mState.compareTo(targetState) < 0 && mObserverMap.contains(observer))) { pushParentState(statefulObserver.mState); // 这里调用 statefulObserver.dispatchEvent(mLifecycleOwner, upEvent(statefulObserver.mState)); popParentState(); // mState / subling may have been changed recalculate targetState = calculateTargetState(observer); } if (!isReentrance) { // we do sync only on the top level. sync(); } mAddingObserverCounter--; }
由于在 State
是个枚举类型 ,RESUME
排在最后,因此是最大的多线程
public enum State { // 删除了无用注释 DESTROYED, INITIALIZED, CREATED, STARTED, RESUMED; }
也就是说,如下代码中ide
while ((statefulObserver.mState.compareTo(targetState) < 0&& mObserverMap.contains(observer))) { pushParentState(statefulObserver.mState); statefulObserver.dispatchEvent(mLifecycleOwner, upEvent(statefulObserver.mState)); popParentState(); // mState / subling may have been changed recalculate targetState = calculateTargetState(observer); } }
若是你想进入循环而且知足调用 upEvent()
发生崩溃的 statefulObserver.mState
值是不存在的,由于 upEvent()
须要 statefulObserver.mState
的值等于RESUMED
, 可是 statefulObserver.mState.compareTo(targetState) < 0
这个恰好就不能是这个条件,RESUMED
是最大的 state
值,是不可能存在其余值比较以后小于0的。spa
当出现这种先后矛盾的时候,大几率就是多线程调用致使了。线程
这个时候咱们就要开始找,还有什么别的方法会致使 statefulObserver.mState
的改变,经过 IDE 的 find usage
能够轻松找到 mState
修改只有下图中的两处
咱们忽略构建方法(由于每次构建的对象不同,不可能同时改),专心再找 dispatchEvent
的使用
排除 addObserver
,重心放在 forwardPass
和 backwardPass
,他们统一调用的方法就是 sync
,经过断点调试就能发现LifeCycleOwner
生命周期改变的时候会调用这个方法。也就是说,若是我使用非UI线程调用 addOboserver
同时改变生命周期就能达到崩溃的条件。调试
咱们在两个地方设置断点,分别是code
而后在 onResume
增长代码server
override fun onResume(){ super.onResume() Thread { lifecycle.addObserver(new ObserverImp()) }.start() }
由于出错的状态是 RESUMED
, 因此你只要 RESUMED
的时候加入 Oboserver
才能获得生命周期报错。操做路径是 App 后台返回前台显示,而后你就会看到
两个线程的显示不是一开始就有的,须要点多几下过,由于须要生命周期调用 addObserver 以后才会开始新线程
这个时候咱们只须要操做 UI 线程停在 RESUME
便可,以下图
这个时候咱们切换到另一个线程, statefulObserver.mState
值就是 RESUME
这个时候点击下一步就是崩溃了。
条件矛盾大几率是线程问题,剩下就是怎么构造多线程修改条件。