首先是你們熟悉的,在fragment中使用startActivityForResult和requestPermissions的時候,要注意:bash
原本我只是知其然但不知其因此然,可是一次debug讓我瞭解了其中緣由。函數
這樣的,我在fragment中發出startActivityForResult請求,在fragment所在的Activity中的onActivityResult打了個斷點看一下,這一看就發現了有個問題:fragment中啓動的requestCode是0,然而到了activity中的onResult的requestCode變成了65536。this
若是是別的數字的話可能會忽略掉,反正最後是能正常調用fragment的回調的,可是65536?2^16??0xffff+1?這個數字但是很特殊。在看了源碼以後終於有了具體的解釋,因此來看看發出請求到onResult的過程吧。spa
聲明: 如下源碼爲API 27.1.1debug
能夠看到Fragment的startActivityForResult調用一個mHost的方法,這個mHost最後就是調用了FragmentActivity的startActivityFromFragment,那FragmentActivity作了什麼呢?
code
requestCode = -1
這是沒有result的startActivity用的,暫且不表,下邊是重要的部分了,check的函數我也放到一塊兒了:
static void checkForValidRequestCode(int requestCode) {
if ((requestCode & 0xffff0000) != 0) {
throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
}
}
...
checkForValidRequestCode(requestCode);
int requestIndex = allocateRequestIndex(fragment);
ActivityCompat.startActivityForResult(
this, intent,
((requestIndex + 1) << 16) + (requestCode & 0xffff), options);
複製代碼
首先是檢查requestCode,高16位不能有1,即requestcode不能大於0xffff,requestIndex能夠理解成fragment的一個標識編號,fragmentActivity來管理的。
重點在這裏: 在實際用ActivityCompact啓動請求的時候,傳入的requestCode並非咱們設置的requestCode了,作了一個轉換,((requestIndex + 1) << 16) + (requestCode & 0xffff)
這個轉換的意思就是requestIndex+1放在高16位,requestCode的低16位放在新的低16位,這樣組成了新的requestCode,寫成數學表達式就是:
requestCode = (requestIndex+1)*0xffff+requeseCode
這樣新的requestCode就是大於0xffff的了。cdn
首先仍是看源碼:blog
嗯..那個check的函數就是上邊那個,因此結果很清楚了。首先咱們要明白,Fragment的請求也是先有FragmentActivity來處理的。而後通過上邊的分析,咱們大概能夠猜想,經過轉換requestCode,Fragment和FragmentActivity的請求就被分開了,那onResult的時候也是分開處理的。來看code:開發
分開來看:get
int requestIndex = requestCode>>16;
if (requestIndex != 0) {
requestIndex--;
...
}
複製代碼
首先是除以(右移)16,這樣剩下的就是高16位,若是不爲0的話,就說明requestCode是大於0xffff的,就是咱們Fragment發出的請求,不爲0的高16位就是requestIndex。下邊就是根據requestIndex找到對應的Fragment了
targetFragment.onActivityResult(
requestCode & 0xffff, resultCode, data);
複製代碼
這是真正調用找到的Fragment的onResult的地方,因爲請求的時候requestCode通過了轉換,因此這裏要轉換回來,取出低16位就是原來的requestCode。
以上是分析了startActivityForResult的流程,requestPermissions是相似的能夠本身去看一遍。源碼真的是好東西,Google的工程師也真的厲害,這個邏輯不難可是讓我這種新手是很差想出來的。
//做爲Android開發的初學者,若是我有錯誤的地方或者不足的話歡迎你們指正。但願與你們一同進步。