Basic usage of fragment storage function in Android application development _android

Source: Internet
Author: User

First, the introduction

In the architecture design of mobile applications, interfaces and data are inseparable and not confusing. In most of the development experience, we are using fragment to interface programming, even if the preservation of data is basically only the interface-related control data, very little to do other data preservation, after all, and the development of the principle of the contrary, and today this blog will introduce the alternative use of fragment, Just to save the data without any interface elements.

Second, the realization of the background

For fragment data preservation methods, it is not difficult to think of the relationship with Setretaininstance. This is where the background is used when screen rotation or other configuration changes are required. Whether in development our interface is generated by activity or fragment, when the screen rotates, the control state and the necessary data are cached in the lifecycle Onsaveinstancestate. Typically, bundle is used to store the data. As bundle's official introduction says, bundle is a map for storing string and other serialized data types. There is also an exception in Android: http://developer.android.com/intl/zh-cn/reference/android/os/TransactionTooLargeException.html

This anomaly is literally not difficult to understand, is the transmission of data is too large exception. In the description, the current Android system is limited to the size of the application's transmission data within 1MB. So it's not very safe to use bundle to cache large data during screen rotation. One of the classic things about this big data on Android is that bitmap, even though bitmap is already a serialized data, makes it easy to use bundle as a caching medium, but I strongly recommend it. Below, it provides a simple solution.

Third, the implementation process

First, create a fragment to hold the data:

public class Bitmapdatafragment extends Fragment {public 
 static final String TAG = "Bitmapsaver"; 
 Private Bitmap Bitmap; 
 
 Private Bitmapdatafragment (Bitmap Bitmap) { 
  this.bitmap = Bitmap; 
 } 
 
 public static bitmapdatafragment newinstance (Bitmap Bitmap) {return 
  new bitmapdatafragment (BITMAP); 
 } 
 
 @Override public 
 void OnCreate (Bundle savedinstancestate) { 
  super.oncreate (savedinstancestate); 
  Setretaininstance (true); 
 
 Public Bitmap GetData () {return 
  Bitmap; 
 } 
} 


This fragment does not have any interface to ensure data security by using Setretaininstance (true) in the OnCreate lifecycle to ensure that it is not destroyed with the carrier.

Once the creation is complete, practice the use process, assuming that the user is an activity:

@Override 
 protected void onsaveinstancestate (Bundle outstate) { 
  if (mbitmap!= null) { 
   Getsupportfragmentmanager (). BeginTransaction () 
     . Add (Bitmapdatafragment.newinstance (Mbitmap), Bitmapdatafragment.tag) 
     . commit (); 
   Outstate.putboolean (Sense_image_key, true); 
  else { 
   Outstate.putboolean (Sense_image_key, false); 
  } 
  Super.onsaveinstancestate (outstate); 
 } 

When a device rotates, detects a bitmap that is displayed in the current interface, and if there is data, the new one we just created fragment, puts the bitmap data in, Then add the fragment to the Fragmentmanager and specify tag so that we can find it conveniently after the state is restored.

At the time of recovery, the life cycle of the activity goes to OnCreate (), where we can determine whether there are bitmap data to be fetched by detecting the bundle parameters:

if (Savedinstancestate.getboolean (Sense_image_key)) { 
  bitmapdatafragment fragment = (bitmapdatafragment) Getsupportfragmentmanager () 
   . Findfragmentbytag (Bitmapdatafragment.tag); 
  Bitmap = Fragment.getdata (); 
  Getsupportfragmentmanager (). BeginTransaction (). Remove (fragment). commit (); 
 

PS: After taking out the bitmap data we need, don't forget to remove the fragment from the Fragmentmanager as the data container and release the system memory it occupies.


Iv. Non-disruptive preservation of fragment

1.setRetaineInstance

First, be clear about what is called "non-disruptive saving." Developers familiar with fragment know that fragment is dependent on activity. When the activity is destroyed, the fragment will be destroyed. And when the activity configuration changes (such as screen rotation), the old activity will be destroyed, and then regenerate a new screen rotation of the activity, the natural fragment will also be destroyed and rebuilt, The objects in the newly generated fragment are not the same as the previous fragment, and their actions and events are different. So, if you want to keep some of the objects in the original fragment, or if you want to keep their movements from being interrupted, there is an urgent need to save the original fragment in a non-disruptive way.

2. Life cycle
the life cycle of an activity changes when the configuration occurs:

Onpuase->onstop->ondestroy->onstart->onresume
For example, a screen rotation occurs in an activity, which is the life cycle. In OnDestroy, the activity destroys the fragment that its Fragmentmanager contains (the default state), that is, the fragment life cycle is:

Ondestroyview->ondestroy->ondetach
By looking at the Fragmentmanager.java code, you can see that the state changes from normal activity_created to created when the fragment lifecycle is executed to Ondestroyview. And by the time the OnDestroy lifecycle, there's something interesting about the code that executes:

if (!f.mretaining) {
 F.performdestroy ();
}
f.mcalled = false;
F.ondetach ();
if (!f.mcalled) {
 throw new supernotcalledexception ("Fragment" + F
  + "did not called through to Super.ondetach ()") ;
}
if (!keepactive) {
 if (!f.mretaining) {
  makeinactive (f);
 } else {
  f.mactivity = null;
  F.mparentfragment = null;
  F.mfragmentmanager = null;
 }
}

When fragment's mretaining is set to True, the destroy lifecycle is not performed, and the fragment mretaining State is configured through its retainnonconfig (). The configuration condition is that fragment is not empty and framgnet mretaininstance is true. Here you can see that if you want your own fragment not to be destroyed, let this mretaininstance be true.

By consulting the Fragment.java source discovery, it can be manipulated through API Setretaininstance and getretaininstance. Similarly, the Android documentation has a certain description of the two interfaces.

Here is a summary of the fragment Fragment.java in conjunction with the comments in Setretaininstance. The original note reads as follows:

/** * Control whether a fragment instance be retained across activity * re-creation (such as From a configuration change). This can only * is used with fragments not in the back stack.  If set, the fragment * lifecycle'll be slightly different as the activity is recreated: * <ul> * <li> {@link #onDestroy ()} would not be called (but {@link #onDetach ()} still * 'll be, because the fragment is being Detache
  D from their current activity).
  * <li> {@link #onCreate (Bundle)} won't be called since the fragment * are not being re-created. * <li> {@link #onAttach (activity)} and {@link #onActivityCreated (Bundle)} <b>will</b> * still is Calle d. * </ul> * public void Setretaininstance (Boolean retain) {if (retain && mparentfragment!= null)
  {throw new IllegalStateException ("Can" T retain fragements that are nested in the other fragments);
 } mretaininstance = retain; }

Set Setretaininstance (TRUE) if you want to call your own fragment and do not destroy them even when their activity is redo. After such an operation, once the activity reorganization phenomenon, fragment will skip OnDestroy direct Ondetach (interface disappeared, objects are still), and framgnet reorganization time will also skip OnCreate, and Onattach and onactivitycreated will still be invoked. It should be noted that the fragment to use this operation cannot be added to the Backstack back stack. Also, the saved fragment instance will not remain too long and will be recycled by the system if it is not hosted by the container for a long time.

V. Summary

Very simple fragment usage, it is really more complicated to save data directly than using bundle, but it is still a good thing to be able to transfer data more securely to the application. Recommended index Five Star ★★★★★!

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.