当我尝试从捆绑包恢复我的活动时,TextView返回Null指针

发布于 2025-01-25 14:35:11 字数 6777 浏览 1 评论 0 原文

我正在尝试使用已保存的实例状态方法来保存文本视图的内容,但它一直返回空指针异常(LogCat:尝试尝试调用虚拟方法'void android.widget.widget.textview.settext(java.lang。 charsequence)'在null对象引用上)。该应用程序在启动时正常工作,但是由于某种原因,当活动被破坏和恢复时,文本视图是无效的(即旋转屏幕时)

 public class MainActivity extends AppCompatActivity {
    private TextView mTextView;

    //other fields
    public static final int MAX_SEATS = 6;
    int numSeats;
    String resultText = "0";
    static final String KEY_RESULT_STRING = "result string";
    static final String KEY_NUM_SEATS = "numberSeats";


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

        if(savedInstanceState != null){
            resultText = savedInstanceState.getString(KEY_RESULT_STRING);
            numSeats = savedInstanceState.getInt(KEY_NUM_SEATS);
            displayResult();
        }
        //variables for widgets
        mTextView = findViewById(R.id.textView);
        //next two lines display "where would you like to sit" on screen
        TextView mIntro = findViewById(R.id.intro);
        mIntro.setText(R.string.introduction);
        EditText mNumRequestedSeats = findViewById(R.id.seatAmountNumberEdit);

        Button reserve = (Button) findViewById(R.id.submit_button);
        reserve.setOnClickListener(view -> {
            //EditText mNumRequestedSeats = findViewById(R.id.seatAmountNumberEdit);
            try{
                String requestedSeats = mNumRequestedSeats.getText().toString();
                numSeats = Integer.parseInt(requestedSeats);
            }
            catch(NumberFormatException wrongSeat){
                Toast.makeText(getApplicationContext(),R.string.wrongFormatError, Toast.LENGTH_SHORT).show();
                numSeats = 0;
            }
            displayResult();
        });
    }
        private void displayResult(){
            if (numSeats > 6){
                resultText = "Please dial 123-456-7890 for parties larger than 6";
            }else {
                resultText = "Thank you for your reservation.";
            }
            mTextView.setText(resultText);
        }
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState){
        savedInstanceState.putString(KEY_RESULT_STRING, resultText);
        savedInstanceState.putInt(KEY_NUM_SEATS, numSeats);
        super.onSaveInstanceState(savedInstanceState);
    }
}

,这是布局文件:



    <?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:id="@+id/numberOfSeats"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/intro"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="16dp"
            android:text="@string/introduction"
            android:textAlignment="center"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
            android:textColor="@color/dark_blue"
            android:textSize="20sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="MissingConstraints">

        </TextView>

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="64dp"
            android:contentDescription="@string/waiter_image"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.497"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/submit_button"
            app:srcCompat="@drawable/waiter" />

        <Button
            android:id="@+id/submit_button"
            style="@style/Widget.MaterialComponents.Button.TextButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:backgroundTint="@color/button_grey"
            android:text="@string/mainActivitySubmit"
            android:textColor="@color/black"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/intro"
            tools:ignore="MissingConstraints" />

        <TextView
            android:id="@+id/seatAmountPrompt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginTop="32dp"
            android:layout_marginEnd="130dp"
            android:text="@string/seatAmount"
            android:textColor="@color/dark_blue"
            android:textSize="16sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView" />

        <EditText
            android:id="@+id/seatAmountNumberEdit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="306dp"
            android:ems="3"
            android:inputType="number"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/seatAmountPrompt" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="64dp"
            android:text="TextView"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/seatAmountNumberEdit" />

    </androidx.constraintlayout.widget.ConstraintLayout>

我尝试使用默认字符串值初始化文本视图,但是当我更改方向时,它仍然带有无效的指针。我在做什么错? 注意:我知道在布局XML中使用TextFreeze之类的内容可能更容易,但是这是一个更复杂的项目的跳板,因此我想学习正确实现保存的捆绑包。

I'm trying to use saved instance state methods to save the contents of a text view but it keeps returning a null pointer exception (LogCat: Attempt to Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference). The app works fine on launch, but for some reason the textView is null when the activity is destroyed and restored (IE when I rotate the screen)

 public class MainActivity extends AppCompatActivity {
    private TextView mTextView;

    //other fields
    public static final int MAX_SEATS = 6;
    int numSeats;
    String resultText = "0";
    static final String KEY_RESULT_STRING = "result string";
    static final String KEY_NUM_SEATS = "numberSeats";


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

        if(savedInstanceState != null){
            resultText = savedInstanceState.getString(KEY_RESULT_STRING);
            numSeats = savedInstanceState.getInt(KEY_NUM_SEATS);
            displayResult();
        }
        //variables for widgets
        mTextView = findViewById(R.id.textView);
        //next two lines display "where would you like to sit" on screen
        TextView mIntro = findViewById(R.id.intro);
        mIntro.setText(R.string.introduction);
        EditText mNumRequestedSeats = findViewById(R.id.seatAmountNumberEdit);

        Button reserve = (Button) findViewById(R.id.submit_button);
        reserve.setOnClickListener(view -> {
            //EditText mNumRequestedSeats = findViewById(R.id.seatAmountNumberEdit);
            try{
                String requestedSeats = mNumRequestedSeats.getText().toString();
                numSeats = Integer.parseInt(requestedSeats);
            }
            catch(NumberFormatException wrongSeat){
                Toast.makeText(getApplicationContext(),R.string.wrongFormatError, Toast.LENGTH_SHORT).show();
                numSeats = 0;
            }
            displayResult();
        });
    }
        private void displayResult(){
            if (numSeats > 6){
                resultText = "Please dial 123-456-7890 for parties larger than 6";
            }else {
                resultText = "Thank you for your reservation.";
            }
            mTextView.setText(resultText);
        }
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState){
        savedInstanceState.putString(KEY_RESULT_STRING, resultText);
        savedInstanceState.putInt(KEY_NUM_SEATS, numSeats);
        super.onSaveInstanceState(savedInstanceState);
    }
}

and here is the layout file:



    <?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:id="@+id/numberOfSeats"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/intro"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="16dp"
            android:text="@string/introduction"
            android:textAlignment="center"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
            android:textColor="@color/dark_blue"
            android:textSize="20sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="MissingConstraints">

        </TextView>

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="64dp"
            android:contentDescription="@string/waiter_image"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.497"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/submit_button"
            app:srcCompat="@drawable/waiter" />

        <Button
            android:id="@+id/submit_button"
            style="@style/Widget.MaterialComponents.Button.TextButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:backgroundTint="@color/button_grey"
            android:text="@string/mainActivitySubmit"
            android:textColor="@color/black"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/intro"
            tools:ignore="MissingConstraints" />

        <TextView
            android:id="@+id/seatAmountPrompt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginTop="32dp"
            android:layout_marginEnd="130dp"
            android:text="@string/seatAmount"
            android:textColor="@color/dark_blue"
            android:textSize="16sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView" />

        <EditText
            android:id="@+id/seatAmountNumberEdit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="306dp"
            android:ems="3"
            android:inputType="number"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/seatAmountPrompt" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="64dp"
            android:text="TextView"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/seatAmountNumberEdit" />

    </androidx.constraintlayout.widget.ConstraintLayout>

I've tried initializing the textView with a default String value but it still comes back with a null pointer when I change orientation. What am I doing wrong?
Note: I know it's probably easier to use something like textFreeze in the layout XML but this is a springboard into a more complicated project so I want to learn to implement saved bundles properly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

赤濁 2025-02-01 14:35:11

请参阅:

您缺少 public void onrestoreInstancestate(bundle savedinstancestate)函数。

更新的答案

我终于有机会正确查看代码。问题是您已放置 findViewById()代码 您调用 display> displayResult() textView 组件尚未初始化/连接,因此它们仍然 null 。 工作的原因 onRestRestate()是因为它被称为在创建活动视图之后被称为
increateview()中的其他所有内容之后重新安置此代码。

if(savedInstanceState != null){
            resultText = savedInstanceState.getString(KEY_RESULT_STRING);
            numSeats = savedInstanceState.getInt(KEY_NUM_SEATS);
            displayResult();
        }

为了增加@sovathna Hong的出色观点,其工作原因是因为未撰写的方法被调用。重要的是,我们必须了解,在两种情况下,都调用 onRestRestate(),当我们不明确地覆盖它时,在的情况下,它只是被自动调用。 null)

Please refer to: https://developer.android.com/guide/components/activities/activity-lifecycle.html#java

You are missing the public void onRestoreInstanceState(Bundle savedInstanceState) function.

UPDATED ANSWER

I finally got a chance to look over the code properly. The issue is that you have placed findViewById() code after you call displayResult(). The TextView components have not been initialized/ hooked up yet, so they're still null. The reason onRestoreState() is working is because it is being called after the Activity view has been created.
Relocate this code after everything else inside onCreateView().

if(savedInstanceState != null){
            resultText = savedInstanceState.getString(KEY_RESULT_STRING);
            numSeats = savedInstanceState.getInt(KEY_NUM_SEATS);
            displayResult();
        }

To add to the excellent point made by @Sovathna Hong, the reason it works is because the non-overwritten method is then being called. It is important that we understand that the onRestoreState() is being called in both cases, it is simply being auto called when we don't explicitly override it in case of if(savedInstanceState != null).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文