Skip to content

Commit

Permalink
Fixed FragmentationMagician's getActiveFragments(), and removed some …
Browse files Browse the repository at this point in the history
…support-library hook methods
  • Loading branch information
YoKeyword committed Jun 7, 2019
1 parent c7e610f commit d62ed3c
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 173 deletions.
Expand Up @@ -2,15 +2,15 @@

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import me.yokeyword.fragmentation.ISupportActivity;
import me.yokeyword.sample.R;

Expand Down
@@ -1,82 +1,19 @@
package androidx.fragment.app;


import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

/**
* http://stackoverflow.com/questions/23504790/android-multiple-fragment-transaction-ordering
* <p>
* Created by YoKey on 16/1/22.
*/
public class FragmentationMagician {
private static boolean sSupportLessThan25dot4 = false;
private static boolean sSupportGreaterThan27dot1dot0 = false;

static {
Field[] fields = FragmentManagerImpl.class.getDeclaredFields();
for (Field field : fields) {
if (field.getName().equals("mStopped")) { // > v27.1.0
sSupportGreaterThan27dot1dot0 = true;
break;
} else if (field.getName().equals("mAvailIndices")) { // < 25.4.0
sSupportLessThan25dot4 = true;
break;
}
}
}

public static boolean isSupportLessThan25dot4() {
return sSupportLessThan25dot4;
}

public static boolean isExecutingActions(FragmentManager fragmentManager) {
if (!(fragmentManager instanceof FragmentManagerImpl))
return false;
try {
FragmentManagerImpl fragmentManagerImpl = (FragmentManagerImpl) fragmentManager;
return fragmentManagerImpl.mExecutingActions;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}

/**
* To fix the FragmentManagerImpl.mAvailIndices incorrect ordering when pop() multiple Fragments
* on pre-support-v4-25.4.0
*/
@SuppressWarnings("unchecked")
public static void reorderIndices(FragmentManager fragmentManager) {
if (!sSupportLessThan25dot4) return;
if (!(fragmentManager instanceof FragmentManagerImpl))
return;
try {
FragmentManagerImpl fragmentManagerImpl = (FragmentManagerImpl) fragmentManager;
Object object = getValue(fragmentManagerImpl, "mAvailIndices");
if (object == null) return;

ArrayList<Integer> arrayList = (ArrayList<Integer>) object;
if (arrayList.size() > 1) {
Collections.sort(arrayList, Collections.reverseOrder());
}
} catch (Exception e) {
e.printStackTrace();
}
}

public static boolean isStateSaved(FragmentManager fragmentManager) {
if (!(fragmentManager instanceof FragmentManagerImpl))
return false;
try {
FragmentManagerImpl fragmentManagerImpl = (FragmentManagerImpl) fragmentManager;
if (sSupportGreaterThan27dot1dot0) {
return fragmentManagerImpl.isStateSaved();
}
return fragmentManagerImpl.mStateSaved;
return fragmentManagerImpl.isStateSaved();
} catch (Exception e) {
e.printStackTrace();
}
Expand Down Expand Up @@ -138,76 +75,26 @@ public void run() {
});
}

/**
* On 25.4.0+,fragmentManager.getFragments () returns mAdd, instead of the mActive on 25.4.0-
*/
@SuppressWarnings("unchecked")
public static List<Fragment> getActiveFragments(FragmentManager fragmentManager) {
if (!(fragmentManager instanceof FragmentManagerImpl))
return Collections.EMPTY_LIST;
// For pre-25.4.0
if (sSupportLessThan25dot4) return fragmentManager.getFragments();

// For compat 25.4.0+
try {
FragmentManagerImpl fragmentManagerImpl = (FragmentManagerImpl) fragmentManager;
// Since v4-25.4.0,mActive: ArrayList -> SparseArray
return getActiveList(fragmentManagerImpl.mActive);
} catch (Exception e) {
e.printStackTrace();
}
return fragmentManager.getFragments();
}

@SuppressWarnings("unchecked")
private static List<Fragment> getActiveList(HashMap<String, Fragment> active) {
if (active == null) {
return Collections.EMPTY_LIST;
}
return new ArrayList<>(active.values());
}

private static Object getValue(Object object, String fieldName) throws Exception {
Field field;
Class<?> clazz = object.getClass();
try {
field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(object);
} catch (Exception e) {
}
return null;
}

private static void hookStateSaved(FragmentManager fragmentManager, Runnable runnable) {
if (!(fragmentManager instanceof FragmentManagerImpl)) return;

FragmentManagerImpl fragmentManagerImpl = (FragmentManagerImpl) fragmentManager;
if (isStateSaved(fragmentManager)) {
boolean tempStateSaved = fragmentManagerImpl.mStateSaved;
boolean tempStopped = fragmentManagerImpl.mStopped;
fragmentManagerImpl.mStateSaved = false;
compatRunAction(fragmentManagerImpl, runnable);
fragmentManagerImpl.mStateSaved = tempStateSaved;
} else {
fragmentManagerImpl.mStopped = false;

runnable.run();
}
}

/**
* Compat v27.1.0+
* <p>
* So the code to compile Fragmentation needs v27.1.0+
*
* @see FragmentManager#isStateSaved()
*/
private static void compatRunAction(FragmentManagerImpl fragmentManagerImpl, Runnable runnable) {
if (!sSupportGreaterThan27dot1dot0) {
fragmentManagerImpl.mStopped = tempStopped;
fragmentManagerImpl.mStateSaved = tempStateSaved;
} else {
runnable.run();
return;
}
boolean tempStopped = fragmentManagerImpl.mStopped;
fragmentManagerImpl.mStopped = false;
runnable.run();
fragmentManagerImpl.mStopped = tempStopped;
}
}
Expand Up @@ -6,16 +6,15 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import androidx.fragment.app.FragmentationMagician;
import me.yokeyword.fragmentation.anim.FragmentAnimator;
import me.yokeyword.fragmentation.helper.internal.AnimatorHelper;
import me.yokeyword.fragmentation.helper.internal.ResultRecord;
Expand Down Expand Up @@ -109,15 +108,8 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
mFragmentAnimator = savedInstanceState.getParcelable(TransactionDelegate.FRAGMENTATION_STATE_SAVE_ANIMATOR);
mIsHidden = savedInstanceState.getBoolean(TransactionDelegate.FRAGMENTATION_STATE_SAVE_IS_HIDDEN);
mContainerId = savedInstanceState.getInt(TransactionDelegate.FRAGMENTATION_ARG_CONTAINER);

// RootFragment
if (mRootStatus != STATUS_UN_ROOT) {
FragmentationMagician.reorderIndices(mFragment.getFragmentManager());
}
}

// Fix the overlapping BUG on pre-24.0.0
processRestoreInstanceState(savedInstanceState);
mAnimHelper = new AnimatorHelper(_mActivity.getApplicationContext(), mFragmentAnimator);

final Animation enter = getEnterAnim();
Expand Down Expand Up @@ -572,18 +564,6 @@ private ISupportFragment getTopFragment() {
return SupportHelper.getTopFragment(getChildFragmentManager());
}

private void processRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState != null) {
FragmentTransaction ft = mFragment.getFragmentManager().beginTransaction();
if (mIsHidden) {
ft.hide(mFragment);
} else {
ft.show(mFragment);
}
ft.commitAllowingStateLoss();
}
}

private void fixAnimationListener(Animation enterAnim) {
// AnimationListener is not reliable.
getHandler().postDelayed(mNotifyEnterAnimEndRunnable, enterAnim.getDuration());
Expand Down
Expand Up @@ -3,11 +3,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
Expand All @@ -17,6 +12,11 @@
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.fragment.app.FragmentationMagician;
import me.yokeyword.fragmentation.exception.AfterSaveStateTransactionWarning;
import me.yokeyword.fragmentation.helper.internal.ResultRecord;
Expand Down Expand Up @@ -170,12 +170,6 @@ public void run() {
removeTopFragment(fm);
FragmentationMagician.popBackStackAllowingStateLoss(fm);
FragmentationMagician.executePendingTransactionsAllowingStateLoss(fm);
mHandler.post(new Runnable() {
@Override
public void run() {
FragmentationMagician.reorderIndices(fm);
}
});
}
});

Expand Down Expand Up @@ -375,8 +369,6 @@ private void doDispatchStartTransaction(FragmentManager fm, ISupportFragment fro
dontAddToBackStack = transactionRecord.dontAddToBackStack;
if (transactionRecord.sharedElementList != null) {
sharedElementList = transactionRecord.sharedElementList;
// Compat SharedElement
FragmentationMagician.reorderIndices(fm);
}
}

Expand Down Expand Up @@ -579,15 +571,6 @@ private void safePopTo(String fragmentTag, final FragmentManager fm, int flag, L
FragmentationMagician.popBackStackAllowingStateLoss(fm, fragmentTag, flag);
FragmentationMagician.executePendingTransactionsAllowingStateLoss(fm);
mSupport.getSupportDelegate().mPopMultipleNoAnim = false;

if (FragmentationMagician.isSupportLessThan25dot4()) {
mHandler.post(new Runnable() {
@Override
public void run() {
FragmentationMagician.reorderIndices(fm);
}
});
}
}

private void mockPopToAnim(Fragment from, String targetFragmentTag, FragmentManager fm, int flag, List<Fragment> willPopFragments, int popAnim) {
Expand Down
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Tue Dec 12 18:11:00 CST 2017
#Sat Jun 08 00:30:18 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

0 comments on commit d62ed3c

Please sign in to comment.