Android onSaveInstanceState onRestoreInstanceState

In this tutorial, we’ll be discussing the two vital methods for managing the state of the application, namely onSaveInstanceState and onRestoreInstanceState.
We’ll be developing a Counter Android Application in which we’ll handle the state of the application when the configuration changes.

在本教程中,我们将讨论管理应用程序状态的两个重要方法,即onSaveInstanceStateonRestoreInstanceState
我们将开发一个Counter Android应用程序,当配置更改时,我们将在其中处理应用程序的状态。

Android生命周期 (Android Lifecycle)

Following is the lifecycle of the Activities in our application:

以下是我们应用程序中活动的生命周期:

Whenever there is a configuration change, such as rotation or application going into multi-window mode, the activity is recreated.

每当进行配置更改(例如轮换或应用程序进入多窗口模式)时,都会重新创建活动。

In this recreation, the application gets restarted and may lose data in the views if not handled properly.

在这种娱乐中,应用程序将重新启动,并且如果处理不当,可能会丢失视图中的数据。

For this there are two methods that are triggered at different stages of the lifecycle:

为此,有两种方法在生命周期的不同阶段触发:

  • onSaveInstanceState

    onSaveInstanceState
  • onRestoreInstanceState

    onRestoreInstanceState

They are used to save and retrieve values. The values are stored in the form of a key-value pair.
Let’s look at each of them separately.

它们用于保存和检索值。 这些值以键值对的形式存储。
让我们分别看一下它们。

onSaveInstanceState (onSaveInstanceState)

onSaveInstanceState method gets called typically before/after onStop() is called. This varies from Android version to version. In the older versions it used to get before onStop().

通常在调用onStop()之前/之后调用onSaveInstanceState方法。 视Android版本而异。 在旧版本中,它通常先于onStop()获得。

Inside this method, we save the important values in the Bundle in the form of key value pairs.

在此方法内部,我们以键值对的形式将重要值保存在Bundle中。

The onSaveInstanceState method looks like :

onSaveInstanceState方法如下所示:

@Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

On the outState bundle instance we add the key value pairs. Following are the methods applicable:

在outState捆绑实例上,我们添加键值对。 以下是适用的方法:

We can pass custom class instances by setting the class as Parcelable or Serializable.

我们可以通过将类设置为Parcelable或Serializable来传递自定义类实例。

Let’s look at an example using Parcelable since it is faster than Serializable.

让我们看一个使用Parcelable的示例,因为它比Serializable更快。

Following is a custom class :

以下是一个自定义类:

public class Model implements Parcelable {
        public long id;
        public String name;

        public Model(long id, String name) {
            this.id = id;
            this.name = name;
        }

        protected Model(Parcel in) {
            id = in.readLong();
            name = in.readString();
        }

        public final Creator<Model> CREATOR = new Creator
   
   
    
    () {
            @Override
            public Model createFromParcel(Parcel in) {
                return new Model(in);
            }

            @Override
            public Model[] newArray(int size) {
                return new Model[size];
            }
        };

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel parcel, int i) {
            parcel.writeLong(id);
            parcel.writeString(name);
        }
    }

   
   

writeToParcel method is where we set the class properties on the Parcelable instance.

writeToParcel方法是我们在writeToParcel实例上设置类属性的地方。

Now create an instance of the Model and save it in onSaveInstanceState.

现在创建Model的实例并将其保存在onSaveInstanceState

Model model = new Model(10, "Hello");

@Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable("parcelable", model);
    }

Now we can retrieve these saved values in the onRestoreInstanceState method.

现在,我们可以在onRestoreInstanceState方法中检索这些保存的值。

Note: onSaveInstanceState gets called whenever you press the home button in your application as well. 注意 :每当您在应用程序中按下主页按钮时,也会调用onSaveInstanceState。

Another note: Things like EditText can save and restore their content implicitly provided you’ve set an id on the View. Activity will automatically collect View’s State from every single View in the View hierarchy.

另一个注意事项 :只要您在View上设置了id,诸如EditText之类的内容就可以隐式保存和恢复其内容。 活动将从视图层次结构中的每个单个视图自动收集视图状态。

onRestoreInstanceState (onRestoreInstanceState)

This method gets triggered only when something was saved in onSaveInstanceState method.
It gets called after onStart().

仅当在onSaveInstanceState方法中保存了某些内容时,才会触发此方法。
它在onStart()之后被调用。

@Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Model model = savedInstanceState.getParcelable("parcelable");
    }

Following are the other method available:

以下是可用的其他方法:

The super method implementation restores the view hierarchy.
超级方法实现可还原视图层次结构。

Generally, onRestoreInstanceState isn’t used to restore values often now. The same can be done from the Bundle in the onCreate method. Also since the onCreate method is always called before, it is a good practice to restore the saved instances there only.

通常, onRestoreInstanceState现在不经常用于还原值。 可以通过onCreate方法中的Bundle完成相同的操作。 另外,由于始终在之前调用onCreate方法,因此,仅在此处还原保存的实例是一种好习惯。

In the following section, we’ll be creating a Counter Application in which we’ll save the state of the counter using the above methods.

在下一节中,我们将创建一个计数器应用程序,在其中使用上述方法保存计数器的状态。

项目结构 (Project Structure)

(Code)

The code for the activity_main.xml is given below:

下面给出了activity_main.xml的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <EditText
        android:id="@+id/inName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Username" />


    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Phone number"
        android:inputType="phone" />


    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        android:textSize="32sp" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="COUNT UP" />


</LinearLayout>

In the above layout, the second EditText doesn’t have any id set. So when the device is rotated or any configuration happens that causes the activity to recreate, this EditText contents would be reset.

在上面的布局中,第二个EditText没有设置任何ID。 因此,当设备旋转或发生任何导致活动重新创建的配置时,此EditText内容将被重置。

The code for the MainActivity.java is given below:

MainActivity.java的代码如下:

package com.journaldev.androidsaverestoreinstance;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Button button;
    TextView textView;
    int counter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState != null) {
            String message = savedInstanceState.getString("message");
            Toast.makeText(this, message, Toast.LENGTH_LONG).show();

            counter = savedInstanceState.getInt("counter", 0);
        }

        button = findViewById(R.id.button);
        textView = findViewById(R.id.textView);
        textView.setText(String.valueOf(counter));


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                counter = Integer.valueOf(textView.getText().toString()) + 1;
                textView.setText(String.valueOf(counter));
            }
        });
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("message", "This is a saved message");
        outState.putInt("counter", counter);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Toast.makeText(getApplicationContext(), "onRestoreInstanceState", Toast.LENGTH_SHORT).show();
        counter = savedInstanceState.getInt("counter", 0);

    }

}

In this the save the integer value of the counter and then when the activity is recreated, the onCreate gets called again. Over there we check if the savedInstanceState Bundle is null or not. If it isn’t we restore the views with the data from the counter.

在这种情况下,保存计数器的整数值,然后在重新创建活动时,再次调用onCreate。 在那儿,我们检查saveInstanceStateState Bundle是否为null。 如果不是,我们将使用计数器中的数据还原视图。

The output of the application in action is given below:

实际应用程序的输出如下:

Notice that the Phone Number field goes empty when the orientation was changed.

请注意,更改方向后,“电话号码”字段为空。

This brings an end to this tutorial. You can download the project from the link below.

本教程到此结束。 您可以从下面的链接下载项目。

翻译自: https://www.journaldev.com/22621/android-onsaveinstancestate-onrestoreinstancestate

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值