Android – when you return to a stopped activity, the fragmentation is exaggerated by old data
Activity a has fragments. When it starts its intention to activity B, when B. finish(), a executes oncreate() again
But this time, even if a.oncreate() has a new packspageradapter and a new viewpager, the fragment will display the old data
I can see that oncreateview() is executed for each fragment, but it still has old parameters because static newinstance() is not called. Parameters will be created when calling getitem (position) of fragmentpageradapter
Here's how it works –
public class PackActivity extends Activity {
...
PacksPagerAdapter mPacksPagerAdapter;
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPacksPagerAdapter = new MyPagerAdapter(getFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mPacksPagerAdapter);
mViewPager.setOffscreenPageLimit(PACK_PAGES - 1);
mViewPager.setOnPagechangelistener(new ViewPager.SimpleOnPagechangelistener() {
@Override
public void onPageSelected(int position) {
actionBar.setTitle(...);
}
});
}
...
}
public class MyPagerAdapter extends FragmentPagerAdapter {
...
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class
// below).
return PackFragment.newInstance(myData);
}
...
}
public class PackFragment extends Fragment {
...
public static PackFragment newInstance(PackInfo pack) {
PackFragment fragment = new PackFragment();
Bundle bdl = new Bundle(2);
bdl.putSerializable(EXTRA_PACK, pack);
bdl.putInt(EXTRA_PACK_POSITION, pack.packNumber);
fragment.setArguments(bdl);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View packView = inflater.inflate(R.layout.pack_fragment, container, false);
// this has the old argument, since newInstance(...) wasn't called
PackInfo pack = (PackInfo) getArguments().getSerializable(EXTRA_PACK);
...
return packView;
}
...
}
Do you know why the new fragment is not instantiated the second time activity a is created?
Update – active fragment lifecycle
As thar said, the answer is that activity is resuming, so old fragments are being reconnected instead of creating new fragments
After spending a lot of time studying this, I found that there are usually three scenarios in the life cycle of active fragments. The following are the scenarios, life cycles and how to reload the old data of fragments:
New activities
Lifecycle: oncreate() = = > onresume() = = > the fragment has been created and attached
There is no need to reload
Resume activity
Lifecycle: oncreate() = = > fragment expands with old data and reconnects = = > onresume()
In onresume(), delete all clips and create new clips, manually or automatically using the adapter –
// Remove all fragments
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
for (int i = BuildConfig.PACK_PAGES - 1; i >= 0; i--) {
Fragment f = findFragmentByPosition(i);
if (f != null)
fragmentTransaction.remove(f);
}
fragmentTransaction.commit();
// This will force recreation of all fragments
viewPager.setAdapter(packsPagerAdapter);
Resume activity
Lifecycle: onresume()
As with active restore, delete the old clip and recreate it
Note: some operating system versions will always resume activity, and other (older) versions will always resume even if settingsactivity is opened within a few seconds
resolvent:
If you post the fragment transaction you submitted in activity a, my answer will be better
I'm not sure if you know - if activity a is recreated when it bounces back from the back stack - this means that it is restored from previous instance state
In this case, you should not execute the transaction again because - it has automatically occurred through the super. Oncreate() activity method. In fact, if you execute fragment trasaction in this case - you will cause the same fragment to be added twice (2 instances)
You can check whether the savedinstancestate parameter is null to see if oncreate() has been called by restoring the instance state
My assumption is that you do not check the savedinstancestate and execute the transaction anyway
If I'm right, the following changes should fix fragment duplication:
Substitute:
public static class ActivityA extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
performFragmentTransaction();
}
Write:
public static class ActivityA extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
performFragmentTransaction();
}
}
More information on – http://developer.android.com/guide/components/fragments.html