Fragmentpageradapter cache for fragment in Android (i)

Source: Internet
Author: User

Viewpager + Fragmentpageradapter, when we often use a pair of partners, the actual application of the code is very simple, but there are some easy to ignore the place, This time we're going to discuss the cache application of Fragmentpageradapter to fragment.

We can first look at the simplest implementation, the custom adapter as follows:

[Code]java Code:?
01020304050607080910111213141516171819202122232425 public class CustomPagerAdapter extends FragmentPagerAdapter{    private List<fragment> mFragments;    public CustomPagerAdapter(FragmentManager fm, List<fragment> fragments) {        super(fm);        this.mFragments = fragments;        fm.beginTransaction().commitAllowingStateLoss();    }    @Override    public Fragment getItem(int position) {        return this.mFragments.get(position);    }    @Override    public int getCount() {        return this.mFragments.size();    }    @Override    public long getItemId(int position) {        return position;    }}</fragment></fragment>

The code is simple, it is not explained, and then the adapter is used in the activity:

[Code]java Code:?
01020304050607080910111213141516 ViewPager pager = (ViewPager) findViewById(R.id.view_pager);List<fragment> fragmentList = new ArrayList<>()TestFragment fragmentOne = new TestFragment();fragmentOne.setText("One");TestFragment fragmentTwo = new TestFragment();fragmentTwo.setText("Two");TestFragment fragmentThree = new TestFragment();fragmentThree.setText("Three"); fragmentList.add(fragmentOne);fragmentList.add(fragmentTwo);fragmentList.add(fragmentThree);CustomPagerAdapter adapter = new CustomPagerAdapter(getSupportFragmentManager(), fragmentList);pager.setAdapter(adapter);</fragment>

This completes the most basic application of a fragmentpageradapter. Now, everything seems to be what we want, but is there really no problem?

Next, let's simulate when the program runs in the background, the Android system because of memory tension, kill our program process situation:

  1. First run the program to the foreground
  2. Next, click the Home button to return to the desktop, and our program is returned to the background to run.
  3. Go to Android Studio, click on Android Monitor tab, select the current device and select the process name of our program.
  4. Click Terminal Application This Little Red fork button, such as:
  5. This time the background process has been killed, but the application history of our application is still in, so long press the home button, and select our program, let it back to the foreground.
  6. You will see that the program does revert to the previous page. But strangely enough, there is only hello on the page, where did we go before we passed in?

Fragment code is also relatively simple, through the log, we find that when recovering, the Mtext field is empty. Therefore, the corresponding TextView on the page cannot be displayed.

[Code]java Code:?
0102030405060708091011121314151617 public class TestFragment extends Fragment {    private String mText;    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_test, container, false);        TextView textView = (TextView) view.findViewById(R.id.center_text_view);        textView.setText(mText);        return view;    }    public void setText(String text) {        this.mText = text;    }}

As we know, the above is the process of killing the back-end app while simulating the memory tension of the Android system. In addition, when the user installs a similar 360 security butler and other applications, choose to clean up the memory, will also trigger the above situation.

Then when the above process occurs, the activity's onsaveinstancestate will be called so that we can save the current user data/page state and so on. When recovering, at OnCreate, we can fetch the previously stored data and then rebind it to the view with the Savedinstancestate parameter.

This process can be understood, but back to our activity code:

[Code]java Code:?
010203040506070809101112 TestFragment fragmentOne = new TestFragment();fragmentOne.setText("One");TestFragment fragmentTwo = new TestFragment();fragmentTwo.setText("Two");TestFragment fragmentThree = new TestFragment();fragmentThree.setText("Three");fragmentList.add(fragmentOne);fragmentList.add(fragmentTwo);fragmentList.add(fragmentThree); CustomPagerAdapter adapter = new CustomPagerAdapter(getSupportFragmentManager(), fragmentList);        pager.setAdapter(adapter);

This code is called in the OnCreate method. When the app resumes from the background, the code is completely executed. In that case, the three fragment have been recreated and the corresponding text values have been set, so why is the Mtext field in fragment still empty?

Is it that the fragment on the screen, and the fragment we instantiate in OnCreate, are already not the same instance?

To verify this idea, add the following log in the OnCreate:

[Code]java Code:?
123 TestFragment fragmentOne = newTestFragment();fragmentOne.setText("One");Log.i("test", "++++fragmentOne++++:"+ fragmentOne.toString());

Also note the log in the Oncreateview method of Testfragment:

[Code]java Code:?
1 Log.i("test", "++++current fragment++++:"+ this.toString());

First run, yes, no problem. Both create and run the same instance 534ed278

[Code]java Code:?
12 I/test: ++++fragmentOne++++:TestFragment{534ed278}I/test: ++++current fragment++++:TestFragment{534ed278 #0id=0x7f0c0066android:switcher:2131492966:0}

Next, we are going to kill the process again and restore the process. The log output is:

[Code]java Code:?
12 I/test: ++++fragmentOne++++:TestFragment{534c5c30}I/test: ++++current fragment++++:TestFragment{534d10d4 #0id=0x7f0c0066android:switcher:2131492966:0}

Amount: Sure enough, this time we created the fragment, and actually passed the Oncreateview fragment. Not the same one (534c5c30/534d10d4).

It seems, or to seek the truth from the source code, open Fragmentpageradapter source, in the Instantiateitem method found the following paragraph:

[Code]java Code:?
01020304050607080910111213 // Do we already have this fragment?String name = makeFragmentName(container.getId(), itemId);Fragment fragment = mFragmentManager.findFragmentByTag(name);if (fragment != null) {    if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);    mCurTransaction.attach(fragment);} else {    fragment = getItem(position);    if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);    mCurTransaction.add(container.getId(), fragment,            makeFragmentName(container.getId(), itemId));}

The Makefragmentname method is as follows:

[Code]java Code:?
123 privatestatic String makeFragmentName(int viewId, long id) {    return "android:switcher:" + viewId + ":"+ id;}

Originally, in the instantiation of fragment, Fragmentpageradapter will first through the makefragmentname return of the tag, to Fragmentmanager to find whether there is the current fragment cache, if any , it restores the previous fragment back and uses it, and instead uses the new instance we passed in.

The makefragmentname generated tag is only affected by the return value of the Getitemid () method that we override, and the current container view's Id,container.getid ().

Here, the problem is clear, because Fragmentpageradapter will take the initiative to fetch the cache of the fragment, so the recovery back after the fragment instance is not the same problem.

As for why the Mtext field is empty, and how to solve the situation, we'll discuss ^_^ in the next chapter.

Fragmentpageradapter cache for fragment in Android (i)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.