1. 程式人生 > >不得不說的那些坑(一)

不得不說的那些坑(一)

V4 26.0.0 FragmentManagerDelegate異常

V4-26.0.0 FragmentManagerDelegate異常

今天敲程式碼的時候。同事給我提了個BUG。我們的表情鍵盤一點就崩潰了。我當時有點發愣,用了半年的東西突然就崩潰了。以前都好好的。
然後我找日誌

目錄

程式碼塊

日誌內容:

  java.lang.IllegalStateException: Fragment 
  EmotionMainFragment{d12508c #1 id=0x7f0d037f EmotionMainFragment} declared target fragment AddShareCommentFragment{4815c41 #2 id=0x7f0d0196 AddShareCommentFragment} that does not belong to this FragmentManager!
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1266) at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java
:1085) at ....

百度了一下,根本沒有這種錯誤過。那麼自力更生,自己動手。
報錯沒有指向對應問題的內容,是在其他地方報的錯。這是最煩的BUG之一了。
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1266)
還有有個線索。FragmentManager 1266行。
下面是複製相關程式碼

FragmentManagerImpl.class

 void
moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) { .... // If we have a target fragment, push it along to at least CREATED // so that this one can rely on it as an initialized dependency. if (f.mTarget != null) { if (!mActive.contains(f.mTarget)) { throw new IllegalStateException("Fragment " + f + " declared target fragment " + f.mTarget + " that does not belong to this FragmentManager!"); } if (f.mTarget.mState < Fragment.CREATED) { moveToState(f.mTarget, Fragment.CREATED, 0, 0, true); } } ...

f.mTarget != null && !mActive.contains(f.mTarget)
這段程式碼分析的結果:
Fragment f設定了mTarget,即使設定了TargetFragment。但是不在mActive( ArrayList mActive)中,Google就能丟不這個錯誤。

IllegalStateException:Fragment f 和你的 mTarget 不是同一個FragmentManager。
那麼我們的mTarget 和 Fragment f確實不是同一個。 mTargetFrament是依附於Activity的。
Fragment 是依附於mTargetFrament的。
然後什麼情況下 要設定TargetFragment呢,需要Frament返回值的時候。
所以當 AActivity 需要 BFrament 返回值, BFrament又需要CFrament(B的子Frament)的時候不能用方法。

異常介面思路:

廢了點時間,找到問題原因了。但是奇怪的是 我之前都是好的。怎麼突然就壞了呢。我沒有改過相關部分的程式碼啊。
總有原因了,這時候我旁邊的安卓同事是沒有問題的。當時想了想,是不是手機問題。
不對,我手機之前也是沒有問題。那麼,就是程式碼不一致了。
同一個程式碼,我次奧 就是Jar前幾個周我更新了!
查看了原始碼。 草泥馬,FragmentManagerImpl.class 26.0.0之前根本沒有我上面的程式碼。
不知道google為什麼在最新包加了這個報錯,之後再研究!!!

總結

問題找到了,根源也找到了。那麼兩個解決思路。
1. jar包降低到26.0.0。
2. BFrament需要子Fragment回撥的時候用其他方式傳值,其他時候可以正常使用,這個情況遇到應該也是比較少的。需要兩次回撥。

誒,被Google坑了一把。擦!我最後使用了第二個解決方式。再坑還是跟著谷歌走吧。