SoFunction
Updated on 2025-03-11

Android RetainFragment state saving method

1. Common state saving and recovery methods

①onSaveInstance + onRestoreInstance

This method is the most general way to implement state saving and recovery. This method is widely used in Android ecosystems, components and Views.

②android:configChanges+onConfigurationChanged

This situation applies to screen rotation and configuration changes, as long as the function is to prevent the activity from being rebuilt, so the adjustment of the [Language] and [Time Zone] may require a restart of the Activity to be updated.

Notice:

Language changes need to be configured as

android:configChanges="locale|layoutDirection"

Screen rotation needs to be configured as

android:configChanges="orientation|keyboard|screenSize"

③onRetainNonConfigurationInstance

This method is a way to replace the Android system in 3.0. The usage scenario is to allow screen rotation, time zone and language adjustment to respond in a timely manner. However, the current system status or tasks that are carried out need to be saved.

Like threaded tasks

public class NetWorkTask extends Thread {
  private volatile ProgressUpdateLinster progressUpdateLinster;
  private Handler handler = new Handler(());

  public NetWorkTask(ProgressUpdateLinster progressUpdateLinster) {
     = progressUpdateLinster;
  }

  private int progress = 0;
  @Override
  public void run() {
    while (progress <= 100) {
      if(progressUpdateLinster != null) {
        (new Runnable() {
         @Override
          public void run() {
            (progress);
          }
        });
      }
      try {
        (200);
      } catch (InterruptedException e) {
        return;
      }
      progress += 2;
    }
  }

  public interface ProgressUpdateLinster {
    void updateProgress(int progress);
  }

  public void cacel() {
    interrupt();
  }
  public void setProgressUpdateLinster(ProgressUpdateLinster progressUpdateLinster) {  
     = progressUpdateLinster;
  }
}

Save status in Activity

private ProgressBar progressBar;
private TextView textView;
private static final String TAG = "MainActivity";

NetWorkTask netWorkTask = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
  (savedInstanceState);
  setContentView(.activity_main);
  progressBar = (ProgressBar) findViewById();
  textView = (TextView) findViewById(.tv_progroess);

  if(getLastCustomNonConfigurationInstance() != null
      &amp;&amp; getLastCustomNonConfigurationInstance() instanceof NetWorkTask) {

     = (NetWorkTask) getLastCustomNonConfigurationInstance(); //Get saved tasks    (linster);
  }else {
     = new NetWorkTask();
    (linster);
    ();
  }

}

private  linster = new () {
  @Override
  public void updateProgress(int progress) {
    (progress);
    (progress+"%");
    (TAG,());
  }
};

/**
 * Save the task
 */
@Override
public Object onRetainCustomNonConfigurationInstance() {
  return netWorkTask;
}

④RetainFragment

The so-called RetainFragment is not a very high-end Fragment. Like DialogFragment, it is relatively ordinary. The RetainFragment here focuses more on [purpose] rather than the name of the Fragment.

Fragment is also an API for Android 3.0, but support-v4 also provides supplementary methods. The principle of saving state is to add Fragment to the FragmentManager transaction, but it is not displayed in the interface (there is no need to implement a view), so it can become a background Fragment.

To implement background fragments, you must not be destroyed during the activity reconstruction. The principle is to implement them through the setRetainInstance method.

public class WorkFragment extends Fragment {

NetWorkTask netWorkTask = null;

/**
  * After reconstruction, the Context here will be automatically replaced with a new activity
  * @param context
  */
@Override
public void onAttach(Context context) {
  (context);
  //When the first startup, the network has not been initialized yet  //After the Activity is rebuilt, update the callback  if(netWorkTask != null) {
    (() context);
  }
}

@Override
public void onDetach() {
  ();
  (null);
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
  (savedInstanceState); //This method will no longer be called after rebuilding  //Set as retain instance Fragment  setRetainInstance(true);
  netWorkTask = new NetWorkTask();
  (() getActivity());
  ();
}
}

How to use it in Activity

public class MainActivity extends AppCompatActivity implements  {

private ProgressBar progressBar;
private TextView textView;
private static final String TAG = "MainActivity";
private static final String TAG_TASK_FRAGMENT = "work";

@Override
protected void onCreate(Bundle savedInstanceState) {
  (savedInstanceState);
  setContentView(.activity_main);
  progressBar = (ProgressBar) findViewById();
  textView = (TextView) findViewById(.tv_progroess);
  
  //If you already have a work fragment, you don't need to create a new one  if(getSupportFragmentManager().findFragmentByTag(TAG_TASK_FRAGMENT) == null) {
    getSupportFragmentManager().beginTransaction().add(new WorkFragment(),TAG_TASK_FRAGMENT).commit();
  }
}

@Override
public void updateProgress(int progress) {
  (progress);
  (progress+"%");
}
}

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.