Title: Difference between Fragment Add and replace, impact on Fragment lifecycle
What is this question about?
- Are you familiar with the application scenarios of Add and replace
- Whether you are familiar with the process after the Fragment transaction operation
Knowledge points investigated
- Application scenarios of Add and replace
- Process after a Fragment transaction
How should the examinee answer
-
Let’s start with the Add and Replace scenarios
When adding a Fragment to an Activity through a transaction, there are two ways to do it: add and replace.
- Add and replace have the same effect when you add only one Fragment to an Activity container.
- The current Activity adds a FragmentA after the FragmentASubsequent operationWhen you want to replace this FragmentA with another FragmentB, there are two situations:
- if
FragmentA
Is added by addFragmentA
Replace withFragmentB
“, you can run the hide commandFragmentA
, the addFragmentB
showFragmentB
- if
FragmentA
Added by the replace operation in theFragmentA
Replace withFragmentB
“, replace with replace
- if
- Added by add
Fragments
, the developer can control which Fragment should be displayed and which Fragment should be hidden. In fact, in the source code, the View in the corresponding Fragment should be displayed and hidden. - With the Fragment added by replace, the existing Fragment is replaced with a life-cycle destruction process, which is passed to the Fragment life-cycle creation process of the replace method.
- Based on the above conclusions, we can draw a conclusion that adding fragments is very important in instance development
- When the Fragment is not visible, if you want to preserve the data in the Fragment and the View’s display state, you can use the Add operation. Later, you can hide and display different fragments for different states.
- Advantages: fast, knowledge Fragment View display and hide
- Disadvantages: Too much data is stored in the memory, which may cause OOM risk.
- When the Fragment is invisible, you don’t need to preserve the data in the Fragment and the View’s display state. Replace can be used instead.
- Advantages: Saves memory and releases unwanted data immediately
- Disadvantages: Frequent creation of fragments, i.e. frequent creation and destruction of the Fragment lifecycle, incurs performance overhead.
- When the Fragment is not visible, if you want to preserve the data in the Fragment and the View’s display state, you can use the Add operation. Later, you can hide and display different fragments for different states.
-
And then to do an add and replace thing operation respectively, how to deal with the source code.
To see how add and replace transactions are handled in the source code, take a look at the commit process for Fragment transactions.
Brief flow chart
Click for a larger version
You can see from the flowchart that the replace operation is modified when step 10 is performed, when the BackStackRecord#expandOps method is called
//BackStackRecord#expandOps Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) { for (int opNum = 0; opNum < mOps.size(); opNum++) { final Op op = mOps.get(opNum); switch (op.cmd) { case OP_ADD: case OP_ATTACH: added.add(op.fragment); break; case OP_REMOVE: case OP_DETACH: { added.remove(op.fragment); } case OP_REPLACE: { final Fragment f = op.fragment; final int containerId = f.mContainerId; boolean alreadyAdded = false; for (int i = added.size() - 1; i >= 0; i--) { // If an existing Fragment is added to the Activity, fetch the added Fragment final Fragment old = added.get(i); if (old.mContainerId == containerId) { if (old == f) { // If replace is the same Fragment alreadyAdded = true; } else { // Delete the old Fragment that is not the same Fragment final Op removeOp = newOp(OP_REMOVE, old); removeOp.enterAnim = op.enterAnim; removeOp.popEnterAnim = op.popEnterAnim; removeOp.exitAnim = op.exitAnim; removeOp.popExitAnim = op.popExitAnim; mOps.add(opNum, removeOp); added.remove(old); opNum++; }}}if (alreadyAdded) { // Remove the currently requested operation from the operation sequence, indicating that the current operation is invalid mOps.remove(opNum); opNum--; } else { // In the current Activity, there is no Fragment added to the same ID or the same ID has a Fragment, but replace passes the Fragment and the existing instance is not the same, change the operation type of replace to addop.cmd = OP_ADD; added.add(f); }}break; }}return oldPrimaryNav; } Copy the code
From the above code analysis
-
If the current Activity has no Fragment added to it, the replace operation is the same as the add operation.
OnAttach ->onCreate->onCreateView->onActivityCreated->onStart-onResume
When the Fragment is destroyed, execute onPause->onStop->onDestoryView->onDestory->onDetach
-
If the current Activity has a Fragment with the same ID, the Fragment instance passed by replace is the same as the existing Fragment instance. Replace has no effect, as can be seen from the above source code
-
If the Activity has a Fragment with the same ID and the Fragment instance passed by replace is different from the existing Fragment instance, the replace operation is converted to remove and add operations. Remove old fragments and add new ones, as can be seen in the code above.
The old Fragment executes onPause->onStop->onDestoryView->onDestory->onDetach
Execute onAttach->onCreate->onCreateView->onActivityCreated->onStart-onResume for the new Fragment
In general, BackStackRecord#expandOps fixes replace to remove and add.
Whether it’s remove or add we find that we’re operating on a collection of mOps. MOps stores sequences of transaction operations. BackStackRecord#executeOps will execute the mOps stored transaction.
void executeOps(a) { final int numOps = mOps.size(); for (int opNum = 0; opNum < numOps; opNum++) { final Op op = mOps.get(opNum); final Fragment f = op.fragment; switch (op.cmd) { case OP_ADD: f.setNextAnim(op.enterAnim); mManager.addFragment(f, false); break; case OP_REMOVE: f.setNextAnim(op.exitAnim); mManager.removeFragment(f); break; case OP_HIDE: f.setNextAnim(op.exitAnim); mManager.hideFragment(f); break; case OP_SHOW: f.setNextAnim(op.enterAnim); mManager.showFragment(f); break; case OP_DETACH: f.setNextAnim(op.exitAnim); mManager.detachFragment(f); break; case OP_ATTACH: f.setNextAnim(op.enterAnim); mManager.attachFragment(f); break; case OP_SET_PRIMARY_NAV: mManager.setPrimaryNavigationFragment(f); break; case OP_UNSET_PRIMARY_NAV: mManager.setPrimaryNavigationFragment(null); break; default: throw new IllegalArgumentException("Unknown cmd: "+ op.cmd); }... }// Execute the Fragment life cycle mManager.moveToState(mManager.mCurState, true); } Copy the code
-
Finally, a brief summary:
When the interviewer asks the difference between add and replace, we can start from the real feeling in the actual use. The essence of replace is to change replace operations into remove and add operations. The old Fragment life cycle destruction process and the new Fragment life cycle creation process are passed.
If you need a more detailed answer from the source point of view, you can answer:
-
If the current Activity has no Fragment added to it, the replace operation is the same as the add operation.
OnAttach ->onCreate->onCreateView->onActivityCreated->onStart-onResume
When the Fragment is destroyed, execute onPause->onStop->onDestoryView->onDestory->onDetach
-
If the Activity has a Fragment with the same ID, the Fragment instance passed by replace is the same as the existing Fragment instance, and the replace has no effect.
-
If the Activity has a Fragment with the same ID and the Fragment instance passed by replace is different from the existing Fragment instance, the replace operation is converted to remove and add operations. Delete old fragments and add new ones.
The old Fragment executes onPause->onStop->onDestoryView->onDestory->onDetach
Execute onAttach->onCreate->onCreateView->onActivityCreated->onStart-onResume for the new Fragment
-
This article is in the open source project: github.com/Android-Alv… Has been included, which contains different directions of self-study programming routes, interview questions set/interviews, and a series of technical articles, etc., resources continue to update…
-