注意到Unable to instantiate fragment com.wonderfull.mobileshop.g.a.a: could not find Fragment constructor
乓序,是說fragment不能被是實例化阳懂,那么問題來了,為什么不能被實例化呢展东,首先赔硫,fragment什么時候會被實例化,當(dāng)然是我們在代碼中去add或者replace這個fragment的時候盐肃,除此以為還有什么地方去實例化fragment嗎爪膊,有权悟,宿主Activity被銷毀后重新恢復(fù)的時候,它的fragment也會被恢復(fù)推盛,進行重新實例化峦阁,這是由系統(tǒng)來完成的,通過反射機制耘成。
好践瓷,說到這荧飞,去瞅瞅源碼晨雳,我們看看fragment的構(gòu)造函數(shù):
/**
* Default constructor. <strong>Every</strong> fragment must have an
* empty constructor, so it can be instantiated when restoring its
* activity's state. It is strongly recommended that subclasses do not
* have other constructors with parameters, since these constructors
* will not be called when the fragment is re-instantiated; instead,
* arguments can be supplied by the caller with {@link #setArguments}
* and later retrieved by the Fragment with {@link #getArguments}.
*
* <p>Applications should generally not implement a constructor. Prefer
* {@link #onAttach(Context)} instead. It is the first place application code can run where
* the fragment is ready to be used - the point where the fragment is actually associated with
* its context. Some applications may also want to implement {@link #onInflate} to retrieve
* attributes from a layout resource, although note this happens when the fragment is attached.
*/
public Fragment() {
}
仔細看函數(shù)注解毫目,我粗略翻譯一下:
“強烈推薦fragment的繼承類不要去實現(xiàn)帶參的構(gòu)造函數(shù),因為這些帶參構(gòu)造函數(shù)在fragment被再次實例化的時候?qū)⒉粫徽{(diào)用师妙,那么這些參數(shù)也就丟失诵肛,建議通過setArguments
方式進行參數(shù)傳遞∧ǎ”
其實這段話還有一層意思曾掂,既然在再次實例化的時候不會調(diào)用我們聲明的帶參構(gòu)造函數(shù),那么必然調(diào)用了無參構(gòu)造函數(shù)壁顶,問題來了,如果你滿足了下面兩個條件:
- 為自己的fragment添加了帶有參數(shù)的構(gòu)造器
- 沒有額外聲明一個無參的構(gòu)造函數(shù)溜歪,或者聲明了若专,但是是private的
那么就悲催了,因為你無意間覆蓋了無參構(gòu)造函數(shù)蝴猪,是的调衰,這樣就會報上面那個異常,通過檢查代碼自阱,確實犯了這個問題嚎莉,莫名其妙的聲明了一個private類型的fragmeng空構(gòu)造器,那么問題也就不可避免了沛豌,之所以說這個問題難遇到趋箩,是因為我們平常確實很少去為fragment聲明其他的構(gòu)造器,但問題出了就要找到原因加派。