How to save state during orientation change in Android if state is made from my classes?

I watched how Android handles orientation changes for my application (I found that it restarts mainactivity when the orientation changes. I saw that you can override the method

protected void onSaveInstanceState(Bundle outState) 

To save material, paste it into onStart. The problem is that I have a view with custom objects and a list using a custom adapter. Everything in the ArrayList of these objects, but I noticed that you cannot put arbitrary objects in the kit! So, how do I save a state?

+52
android
Oct 12 2018-10-12
source share
6 answers

EDIT: In newer versions of Android and with the compatibility library, saved fragments are usually the best way to process data that stores expensive data to restore activity when it destroys / creates activity. And, as Dianne pointed out, saving configuration data was to optimize things such as generating thumbnails that are economical for performance reasons, but are not critical to the functioning of your activities, if you need to redo them, this will not replace the correct storage and restoration of the activity state.

But back when I first answered this in 2010:
If you want to save your own data (not viewing state), you can actually pass an arbitrary object specifically for changing the orientation using onRetainNonConfigurationInstance() . See this post on the Android Developers Blog . Just be careful not to put any Views or other references to the preliminary turn of the Context / Activity in the object you are passing, or you will prevent the collection of these garbage and possibly end up running out of memory (this is called a context leak ).

+42
Oct 12 '10 at 15:05
source share

You tried to use: his work is around,

 <activity name= ".YourActivity" android:configChanges="orientation|screenSize"/> 

in the manifest file?

This does not work by default, because when you change the orientation, onCreate will be called again and it will redraw your view.

If you write this parameter, you do not need to contact the Activity, the structure will take care of the rest. When you change the orientation, it will save the state of the screen or layout.

NOTE If you use a different layout for landscape mode by adding these options, the layout for landscape mode will not be called.

Another way and Another way

+137
Aug 21 2018-12-12T00:
source share

First, you need to determine what is actually a “state” in your application. You did not say what you are actually doing, but let me assume that the ArrayList is the state the user is working with.

Secondly, determine what the life cycle of this condition really is. Is this really related to this activity? Or should the user not lose it if its battery runs out, the device turns off, and then returns to your application? If the first, onSaveInstanceState() correct; if the latter, you want to store in persistent storage in onPause() .

For onSaveInstanceState() with custom objects, the key must implement the Parcelable interface. This includes implementing methods on Parcelable, as well as creating a static CREATOR object in your class. Here is the code for a typical simple Parcelable class:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java

Key features are the implementation of Parcelable:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java#317

and the static class CREATOR:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java#355

(The static writeToParcel() and readFromParcel() are just the amenities that were made for this class and are not required.)

Now that you have this, you can put your entire ArrayList into the saved Bundle state with the Bundle.putParcelableArrayList :

http://developer.android.com/reference/android/os/Bundle.html#putParcelableArrayList (java.lang.String, java.util.ArrayList)

In Activity.onCreate() , check if you have a savedState Bundle , and if so, try extracting an ArrayList from it and use it if it is found by creating a new adapter and a list view for the new action that is used to display it.

+16
Oct 12 '10 at 17:05
source share

but I noticed that you cannot put arbitrary objects in a package!

First create your custom Parcelable objects.
Then you can put them in a package.

Everything is in the ArrayList of these objects

You can use the putParcelableArrayList method in a package to store an ArrayList array with custom “picky” objects.

+3
On May 01 '13 at 21:16
source share

write your objects in JSON Strings using Google Gson, then save them as a string. Then return them from saved JSON strings when restoring Activity / Fragment

 import com.google.gson.Gson; public class MyClass { private int a; private String s; private OtherSerializableClass other; private List<String> list; public String toJson() { return new Gson().toJson(this); } public static ChatAPI_MessagesArray fromJson(String json){ return new Gson().fromJson(json, YourClass.class); } // Getters ... // Setters ... } 
+3
May 02 '15 at 8:17
source share

For simple data, an action can use the onSaveInstanceState () method and restore its data from the package to onCreate (), but this approach is suitable only for small amounts of data that can be serialized and then deserialized, but not for potentially large amounts of data. like a user list or bitmap.

 The ViewModel class allows data to survive configuration changes such as screen rotations. Architecture Components provides ViewModel helper class for the UI controller that is responsible for preparing data for the UI. **Example**: 

if you need to display the list of users in your application, make sure that you assign responsibility for acquiring and maintaining the list of users on the ViewModel instead of an action or fragment, as shown in the following code example.

 public class MyViewModel extends ViewModel { private MutableLiveData<List<User>> users; public LiveData<List<User>> getUsers() { if (users == null) { users = new MutableLiveData<List<User>>(); loadUsers(); } return users; } private void loadUsers() { // Do an asynchronous operation to fetch users. } } public class MyActivity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { // Create a ViewModel the first time the system calls an activity onCreate() method. // Re-created activities receive the same MyViewModel instance created by the first activity. MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class); model.getUsers().observe(this, users -> { // update UI }); } } 
0
Jun 26 '19 at 7:41
source share



All Articles