17
17
package android .support .v4 .app ;
18
18
19
19
import android .content .Context ;
20
+ import android .content .Intent ;
20
21
import android .content .res .Configuration ;
21
22
import android .content .res .TypedArray ;
22
23
import android .os .Bundle ;
51
52
import java .io .PrintWriter ;
52
53
import java .util .ArrayList ;
53
54
import java .util .Arrays ;
55
+ import java .util .HashSet ;
54
56
import java .util .List ;
55
57
56
58
/**
@@ -357,20 +359,25 @@ public FragmentTransaction openTransaction() {
357
359
public static void enableDebugLogging (boolean enabled ) {
358
360
FragmentManagerImpl .DEBUG = enabled ;
359
361
}
362
+
363
+ abstract int getActivityRequestCode (Fragment fragment );
364
+ abstract void onActivityResult (int requestCode , int resultCode , Intent data );
360
365
}
361
366
362
367
final class FragmentManagerState implements Parcelable {
363
368
FragmentState [] mActive ;
364
369
int [] mAdded ;
365
370
BackStackState [] mBackStack ;
366
-
371
+ ActivityRequest [] mPendingActivityRequests ;
372
+
367
373
public FragmentManagerState () {
368
374
}
369
375
370
376
public FragmentManagerState (Parcel in ) {
371
377
mActive = in .createTypedArray (FragmentState .CREATOR );
372
378
mAdded = in .createIntArray ();
373
379
mBackStack = in .createTypedArray (BackStackState .CREATOR );
380
+ mPendingActivityRequests = in .createTypedArray (ActivityRequest .CREATOR );
374
381
}
375
382
376
383
public int describeContents () {
@@ -381,6 +388,7 @@ public void writeToParcel(Parcel dest, int flags) {
381
388
dest .writeTypedArray (mActive , flags );
382
389
dest .writeIntArray (mAdded );
383
390
dest .writeTypedArray (mBackStack , flags );
391
+ dest .writeTypedArray (mPendingActivityRequests , flags );
384
392
}
385
393
386
394
public static final Parcelable .Creator <FragmentManagerState > CREATOR
@@ -403,6 +411,47 @@ interface FragmentContainer {
403
411
public boolean hasView ();
404
412
}
405
413
414
+ final class ActivityRequest implements Parcelable {
415
+ final int mFragmentIndex ;
416
+ final int mRequestIndex ;
417
+ final int mChildRequestIndex ;
418
+
419
+ ActivityRequest (int fragmentIndex , int requestIndex , int childRequestIndex ) {
420
+ mFragmentIndex = fragmentIndex ;
421
+ mRequestIndex = requestIndex ;
422
+ mChildRequestIndex = childRequestIndex ;
423
+ }
424
+
425
+ ActivityRequest (Parcel in ) {
426
+ mFragmentIndex = in .readInt ();
427
+ mRequestIndex = in .readInt ();
428
+ mChildRequestIndex = in .readInt ();
429
+ }
430
+
431
+ @ Override
432
+ public int describeContents () {
433
+ return 0 ;
434
+ }
435
+
436
+ @ Override
437
+ public void writeToParcel (Parcel dest , int flags ) {
438
+ dest .writeInt (mFragmentIndex );
439
+ dest .writeInt (mRequestIndex );
440
+ dest .writeInt (mChildRequestIndex );
441
+ }
442
+
443
+ public static final Parcelable .Creator <ActivityRequest > CREATOR
444
+ = new Parcelable .Creator <ActivityRequest >() {
445
+ public ActivityRequest createFromParcel (Parcel in ) {
446
+ return new ActivityRequest (in );
447
+ }
448
+
449
+ public ActivityRequest [] newArray (int size ) {
450
+ return new ActivityRequest [size ];
451
+ }
452
+ };
453
+ }
454
+
406
455
/**
407
456
* Container for fragments associated with an activity.
408
457
*/
@@ -426,7 +475,9 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate
426
475
ArrayList <Integer > mAvailIndices ;
427
476
ArrayList <BackStackRecord > mBackStack ;
428
477
ArrayList <Fragment > mCreatedMenus ;
429
-
478
+ ArrayList <ActivityRequest > mPendingActivityRequests ;
479
+ ArrayList <Integer > mAvailRequestIndices ;
480
+
430
481
// Must be accessed while locked.
431
482
ArrayList <BackStackRecord > mBackStackIndices ;
432
483
ArrayList <Integer > mAvailBackStackIndices ;
@@ -743,6 +794,77 @@ public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[]
743
794
}
744
795
}
745
796
797
+ @ Override
798
+ int getActivityRequestCode (Fragment fragment ) {
799
+ return getActivityRequestIndex (fragment , -1 ) + 1 ;
800
+ }
801
+
802
+ private int getActivityRequestIndex (Fragment fragment , int childRequestIndex ) {
803
+ final ActivityRequest request ;
804
+
805
+ if (mAvailRequestIndices == null || mAvailRequestIndices .isEmpty ()) {
806
+ if (mPendingActivityRequests == null ) {
807
+ mPendingActivityRequests = new ArrayList <ActivityRequest >();
808
+ }
809
+
810
+ if (mPendingActivityRequests .size () > 0xffff ) {
811
+ throw new IllegalStateException ("Over 0xffff pending activity requests in " + fragment );
812
+ }
813
+
814
+ request = new ActivityRequest (fragment .mIndex , mPendingActivityRequests .size (), childRequestIndex );
815
+ mPendingActivityRequests .add (request );
816
+ } else {
817
+ request = new ActivityRequest (fragment .mIndex , mAvailRequestIndices .remove (mAvailRequestIndices .size () - 1 ), childRequestIndex );
818
+ mPendingActivityRequests .set (request .mRequestIndex , request );
819
+ }
820
+
821
+ Fragment parent = fragment .getParentFragment ();
822
+ if (parent != null ) {
823
+ return parent .mFragmentManager .getActivityRequestIndex (parent , request .mRequestIndex );
824
+ } else {
825
+ return request .mRequestIndex ;
826
+ }
827
+ }
828
+
829
+ @ Override
830
+ void onActivityResult (int requestCode , int resultCode , Intent data ) {
831
+ if (!dispatchOnActivityResult ((requestCode >>16 ) - 1 , requestCode , resultCode , data )) {
832
+ Log .w (TAG , "No fragment exists for requestCode: 0x" + Integer .toHexString (requestCode ));
833
+ }
834
+ }
835
+
836
+ private boolean dispatchOnActivityResult (int requestIndex , int requestCode , int resultCode , Intent data ) {
837
+ if (!checkElement (mPendingActivityRequests , requestIndex )) {
838
+ return false ;
839
+ }
840
+
841
+ ActivityRequest resultRequest = mPendingActivityRequests .get (requestIndex );
842
+ if (!checkElement (mActive , resultRequest .mFragmentIndex )) {
843
+ return false ;
844
+ }
845
+
846
+ Fragment fragment = mActive .get (resultRequest .mFragmentIndex );
847
+ if (resultRequest .mChildRequestIndex != -1 ) {
848
+ mPendingActivityRequests .set (requestIndex , null );
849
+ if (mAvailRequestIndices == null ) {
850
+ mAvailRequestIndices = new ArrayList <Integer >();
851
+ }
852
+ mAvailRequestIndices .add (requestIndex );
853
+
854
+ return fragment .mChildFragmentManager .dispatchOnActivityResult (
855
+ resultRequest .mChildRequestIndex ,
856
+ requestCode , resultCode , data
857
+ );
858
+ } else {
859
+ fragment .onActivityResult (requestCode , resultCode , data );
860
+ return true ;
861
+ }
862
+ }
863
+
864
+ private boolean checkElement (ArrayList <?> list , int index ) {
865
+ return list != null && index < list .size () && list .get (index ) != null ;
866
+ }
867
+
746
868
static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator (2.5f );
747
869
static final Interpolator DECELERATE_CUBIC = new DecelerateInterpolator (1.5f );
748
870
static final Interpolator ACCELERATE_QUINT = new AccelerateInterpolator (2.5f );
@@ -1774,11 +1896,18 @@ Parcelable saveAllState() {
1774
1896
}
1775
1897
}
1776
1898
}
1777
-
1899
+
1900
+ // Save pending activity requests
1901
+ ActivityRequest [] pendingActivityRequests = null ;
1902
+ if (mPendingActivityRequests != null ) {
1903
+ pendingActivityRequests = mPendingActivityRequests .toArray (new ActivityRequest [mPendingActivityRequests .size ()]);
1904
+ }
1905
+
1778
1906
FragmentManagerState fms = new FragmentManagerState ();
1779
1907
fms .mActive = active ;
1780
1908
fms .mAdded = added ;
1781
1909
fms .mBackStack = backStack ;
1910
+ fms .mPendingActivityRequests = pendingActivityRequests ;
1782
1911
return fms ;
1783
1912
}
1784
1913
@@ -1893,6 +2022,22 @@ void restoreAllState(Parcelable state, ArrayList<Fragment> nonConfig) {
1893
2022
} else {
1894
2023
mBackStack = null ;
1895
2024
}
2025
+
2026
+ // Restore pending activity requests
2027
+ if (fms .mPendingActivityRequests != null ) {
2028
+ mPendingActivityRequests = new ArrayList <ActivityRequest >();
2029
+ if (mAvailRequestIndices != null ) {
2030
+ mAvailRequestIndices .clear ();
2031
+ } else {
2032
+ mAvailRequestIndices = new ArrayList <Integer >();
2033
+ }
2034
+ for (int i =0 ; i <fms .mPendingActivityRequests .length ; i ++) {
2035
+ if (fms .mPendingActivityRequests [i ] == null ) {
2036
+ mAvailRequestIndices .add (i );
2037
+ }
2038
+ }
2039
+ mPendingActivityRequests = new ArrayList <ActivityRequest >(Arrays .asList (fms .mPendingActivityRequests ));
2040
+ }
1896
2041
}
1897
2042
1898
2043
public void attachActivity (FragmentActivity activity ,
0 commit comments