【发布时间】:2020-08-08 12:49:35
【问题描述】:
我正在进行项目,但我在活动和保存状态方面遇到了一些问题。所以我回到了基础,试图了解我错过了什么。但是,即使设置非常简单,我也遇到了同样的问题。
所以我从一个空项目开始,在 activity_main.xml 上放置了 2 个 textView 和 1 个按钮,在 activity_2.xml 上放置了 1 个按钮。用户将在文本框中输入一些文本,按下按钮前进到 Activity2 Activity,然后按下按钮(在 Activity2 布局中)返回到 MainActivity。
我希望输入到文本框中的文本已被重写的 onSaveInstanceState 方法保存,然后 OnCreate 中的 bundle 参数将保存此值。但是,当 MainActivity 被点击时,尽管在按下启动 Activity2 的按钮时调用了 onSaveInstanceState,但捆绑包仍然为 null。
我错过了什么吗? onSaveInstanceState 方法肯定是启动的,并在其中填充了 savedInstanceState,那么为什么当 MainActivity 再次启动并调用 onCreate 时,Bundle savedInstanceState 为空?这是我设置开始其他活动的方式吗?
感谢您的帮助!
作为参考,这是我的设置:
我的主要活动:
public class MainActivity extends AppCompatActivity {
Button forwardButton;
TextView editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
forwardButton = findViewById(R.id.buttonForward);
editText = findViewById(R.id.editText);
forwardButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
Intent activity2 = new Intent(MainActivity.this,Activity2.class);
startActivity(activity2);
}
});
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
String textToSave = editText.getText().toString();
savedInstanceState.putString("editText",textToSave);
super.onSaveInstanceState(savedInstanceState);
}
}``
我的 Activity2 课:
public class Activity2 extends AppCompatActivity {
Button goBack;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
goBack = findViewById(R.id.goBack);
goBack.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Code here executes on main thread after user presses button
Intent activity2 = new Intent(Activity2.this,MainActivity.class);
startActivity(activity2);
}
});
}
}
Activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/buttonForward"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="162dp"
android:layout_marginTop="232dp"
android:layout_marginEnd="162dp"
android:layout_marginBottom="76dp"
android:text="Forward"
app:layout_constraintBottom_toTopOf="@+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="96dp"
android:layout_marginTop="43dp"
android:layout_marginEnd="102dp"
android:layout_marginBottom="268dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Enter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
activity_2.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity2">
<Button
android:id="@+id/goBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="162dp"
android:layout_marginTop="232dp"
android:layout_marginEnd="162dp"
android:layout_marginBottom="76dp"
android:text="Go back"
app:layout_constraintBottom_toTopOf="@+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
【问题讨论】:
-
"那么为什么当 MainActivity 再次启动并调用 onCreate 时,Bundle savedInstanceState 为空?" -- 因为它是一个完全不同的活动实例。除了属于同一类之外,它与您的原始实例完全无关,因为您启动了第二个实例。如果您想让
Activity2返回到您现有的MainActivity实例,请在您的onClick()方法中调用finish(),而不是startActivity()。 -
@CommonsWare 好的,谢谢 - 这是有道理的。所以说我想添加第三个活动,当完成后返回到第二个活动,finish() 方法如何知道然后返回到哪个活动 - 它是活动开始的地方吗?其次,假设应用程序是从头开始加载的,它需要上一个会话的数据——我是否需要在 onDestroy() 上序列化上一个会话的数据,然后在 MainActivity 的第一个 onCreate 上重新加载?跨度>
-
另外,这是否意味着 onCreate 和输入包参数在 Activity 更改之间根本没有被调用或有用?即它们仅在发生方向更改或应用程序从头开始完全重新启动并且需要从存储中加载数据时使用?在后一种情况下,输入的 bundle 参数仍然是 null 正确的吗?
-
“finish() 方法如何知道要返回哪个活动 - 它是活动开始的地方吗?” -- 控制返回到它在后堆栈上的任何活动。 “我是否需要在 onDestroy() 上序列化上一个会话中的数据,然后在 MainActivity 中的第一个 onCreate 上重新加载?” -- 您需要将数据保存在某个地方。通常,当数据发生变化时,您会这样做,因为不能保证调用
onDestroy()。 -
“它们仅在发生方向变化等情况时使用”——这是主要场景。有关更多信息,请参阅the documentation 和有关 Android 应用程序开发的书籍。
标签: java android android-activity android-context android-savedstate