【问题标题】:Fragment onSaveInstanceState crashing app on screen rotation屏幕旋转上的片段 onSaveInstanceState 使应用程序崩溃
【发布时间】:2016-01-24 02:18:33
【问题描述】:

我有一个带有片段的应用程序。其中一个片段要求用户在 2 个文本字段中输入团队名称。我想将名称保存在 onSaveInstanceState 中。但是,当我移动到另一个片段并旋转屏幕时,这有效,我得到下面的错误,指向我试图保存的edittext字段。有谁知道我在这里做错了什么。我得到一个 NullPointerException 但我不知道为什么。谢谢!

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“android.view.View android.view.View.findViewById(int)”

错误指向,

EditText teamAname = (EditText) mView.findViewById(R.id.teamAname);

//Save data
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    setUserVisibleHint(false);

    savedInstanceState.putInt("TeamATry", TeamATry);
    savedInstanceState.putInt("TeamBTry", TeamBTry);
    EditText teamAname = (EditText) mView.findViewById(R.id.teamAname);
    teamAname.setInputType(InputType.TYPE_CLASS_TEXT);
    String teamAnametext = teamAname.getText().toString();
    EditText teamBname = (EditText) mView.findViewById(R.id.teamBname);
    teamBname.setInputType(InputType.TYPE_CLASS_TEXT);
    String teamBnametext = teamBname.getText().toString();
    savedInstanceState.putInt("TeamAConvert", TeamAConvert);
    savedInstanceState.putInt("TeamBConvert", TeamBConvert);
    savedInstanceState.putInt("TeamAPenalty", TeamAPenalty);
    savedInstanceState.putInt("TeamBPenalty", TeamBPenalty);
    savedInstanceState.putInt("TeamAScore", TeamAscore);
    savedInstanceState.putInt("TeamBScore", TeamBscore);
    savedInstanceState.putString("TeamAname", teamAnametext);
    savedInstanceState.putString("TeamBname", teamBnametext);
    super.onSaveInstanceState(savedInstanceState);
    Log.i("4", teamAnametext + "Saved");
    Log.i("4", "Match Frag Scores saved");
    super.onSaveInstanceState(savedInstanceState);
}

OnCreateView 代码

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        //Inflate rugby layout
        View rootview = inflater.inflate(R.layout.rugbycounter, container, false);
        this.mView = rootview;
        //This will show the menu
        setHasOptionsMenu(true);

        //Load saved state
        if(savedInstanceState!=null)
        {
            teamAnametext = savedInstanceState.getString("TeamAname");
            teamBnametext = savedInstanceState.getString("TeamBname");
            TeamATry = savedInstanceState.getInt("TeamATry");
            TeamBTry = savedInstanceState.getInt("TeamBTry");
            TeamAConvert = savedInstanceState.getInt("TeamAConvert");
            TeamBConvert = savedInstanceState.getInt("TeamBConvert");
            TeamAPenalty = savedInstanceState.getInt("TeamAPenalty");
            TeamBPenalty = savedInstanceState.getInt("TeamBPenalty");
            TeamAscore = savedInstanceState.getInt("TeamAScore");
            TeamBscore = savedInstanceState.getInt("TeamBScore");
            Log.i("Assign4", "Score values restored");
        }
        return rootview;
    }

Rugbycounter.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"

    xmlns:android="http://schemas.android.com/apk/res/android">
    <!--Scrollview to handle horizontal orientation-->
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <!--Linear Layout for top section of buttons-->
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            >
            <!--Table layout with two columns-->
            <TableLayout
                android:id="@+id/tableLayout1"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:stretchColumns="0,1"
                android:layout_marginTop="10dp"
                android:divider="@color/actionbar_background"
                android:showDividers="middle"
                android:dividerPadding="5dp">

                <TableRow
                    android:id="@+id/tableRow1"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp">

                    <EditText
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:id="@+id/teamAname"
                        android:text="@+id/teamAname"
                        android:hint="@string/hintEnterTeamA"
                        android:layout_column="0"
                        android:gravity="center"
                        android:freezesText="true" >
                    </EditText>

                    <EditText
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:id="@+id/teamBname"
                        android:text="@+id/teamBname"
                        android:hint="@string/hintEnterTeamB"
                        android:layout_column="1"
                        android:gravity="center"
                        android:freezesText="true"
                        android:layout_marginStart="1dp">
                    </EditText>

                </TableRow>

                <TableRow
                    android:id="@+id/tableRow2"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp">

                    <TextView
                        android:textAppearance="?android:attr/textAppearanceLarge"
                        android:text="@+id/teamAscore"
                        android:id="@+id/teamAscore"
                        android:layout_column="0"
                        android:gravity="center"
                        android:textSize="50sp"
                        android:textStyle="bold"
                        android:singleLine="true"
                        android:freezesText="true" >
                    </TextView>

                    <TextView
                        android:textAppearance="?android:attr/textAppearanceLarge"
                        android:text="@+id/teamBscore"
                        android:id="@+id/teamBscore"
                        android:layout_column="1"
                        android:gravity="center"
                        android:textStyle="bold"
                        android:textSize="50sp"
                        android:freezesText="true" >
                    </TextView>

                </TableRow>

                <TableRow
                    android:id="@+id/tableRow3"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp">

                    <Button
                        style="?android:attr/buttonStyleSmall"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/penalty3"
                        android:id="@+id/aPenalty"
                        android:layout_marginLeft="10dp"
                        android:layout_marginRight="10dp"
                        android:layout_column="0" />

                    <Button
                        style="?android:attr/buttonStyleSmall"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/penalty3"
                        android:id="@+id/bPenalty"
                        android:layout_marginLeft="10dp"
                        android:layout_marginRight="10dp"
                        android:layout_column="1" />

                </TableRow>

                <TableRow
                    android:id="@+id/tableRow4"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp">

                    <Button
                        style="?android:attr/buttonStyleSmall"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/conversion2"
                        android:id="@+id/aConversion"
                        android:layout_marginLeft="10dp"
                        android:layout_marginRight="10dp"
                        android:layout_column="0" />

                    <Button
                        style="?android:attr/buttonStyleSmall"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/conversion2"
                        android:id="@+id/bConversion"
                        android:layout_marginLeft="10dp"
                        android:layout_marginRight="10dp"
                        android:layout_column="1" />

                </TableRow>

                <TableRow
                    android:id="@+id/tableRow5"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="10dp">

                    <Button
                        style="?android:attr/buttonStyleSmall"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/try5"
                        android:id="@+id/aTry"
                        android:layout_marginLeft="10dp"
                        android:layout_marginRight="10dp"
                        android:layout_column="0" />

                    <Button
                        style="?android:attr/buttonStyleSmall"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/try5"
                        android:id="@+id/bTry"
                        android:layout_marginLeft="10dp"
                        android:layout_marginRight="10dp"
                        android:layout_column="1" />

                </TableRow>

            </TableLayout>
            <!--Linear layout to create separation between top and bottom layout-->
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="50dp">

            </LinearLayout>
            <!--Linear Layout for bottom 3 buttons-->
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="2"
                android:paddingStart="10dp"
                android:paddingEnd="10dp"
                android:gravity="center_horizontal">

                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/reset"
                    android:id="@+id/resetButton"
                    android:height="50dp"
                    android:layout_marginBottom="10dp"
                    android:layout_marginStart="5dp"
                    android:paddingLeft="10dp"
                    android:paddingRight="10dp"/>

                <Button
                    style="?android:attr/buttonStyleSmall"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/SUMMARY"
                    android:id="@+id/summaryButton"
                    android:layout_gravity="end"
                    android:height="50dp"
                    android:layout_marginEnd="5dp"
                    android:layout_marginStart="40dp"
                    android:paddingLeft="10dp"
                    android:paddingRight="10dp"/>

            </LinearLayout>
        </LinearLayout>
    </ScrollView>
</LinearLayout>

【问题讨论】:

  • 显示你的 onCreateView() 代码
  • 我已经添加了我的 onCreateView 代码。看起来还可以吗?
  • 嗨丹尼尔,谢谢!你能告诉我一个使用成员变量来实现这个引用目的的例子吗?

标签: java android android-fragments


【解决方案1】:

将所有对 findViewById() 的调用移至您的 onCreateView() 方法,并使用成员变量来保留对您的 EditText 字段的引用。您不应该在 onSaveInstanceState() 方法中调用 findViewById()。

在您的 Fragment 类定义中,将 EditText 字段定义为该类的成员变量:

public class MyFragment extends Fragment {
    EditText teamAname;
    EditText teamBname;
    //.......

然后在onCreateView()中初始化它们:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    //Inflate rugby layout
    View rootview = inflater.inflate(R.layout.rugbycounter, container, false);

    //Not needed, don't do this:
    //this.mView = rootview;

    //This will show the menu
    setHasOptionsMenu(true);

    //Add this:
    teamAname = (EditText) rootview.findViewById(R.id.teamAname);
    teamBname = (EditText) rootview.findViewById(R.id.teamBname);
    teamAname.setInputType(InputType.TYPE_CLASS_TEXT);
    teamBname.setInputType(InputType.TYPE_CLASS_TEXT);

    //Null check:
    if (teamAname == null) {
           Toast.makeText(this, "teamAname null", Toast.LENGTH_LONG).show();
    }

    if (teamBname == null) {
           Toast.makeText(this, "teamBname null", Toast.LENGTH_LONG).show();
    }

    //Load saved state
    if(savedInstanceState!=null)
    {
        teamAnametext = savedInstanceState.getString("TeamAname");
        teamBnametext = savedInstanceState.getString("TeamBname");
        TeamATry = savedInstanceState.getInt("TeamATry");
        TeamBTry = savedInstanceState.getInt("TeamBTry");
        TeamAConvert = savedInstanceState.getInt("TeamAConvert");
        TeamBConvert = savedInstanceState.getInt("TeamBConvert");
        TeamAPenalty = savedInstanceState.getInt("TeamAPenalty");
        TeamBPenalty = savedInstanceState.getInt("TeamBPenalty");
        TeamAscore = savedInstanceState.getInt("TeamAScore");
        TeamBscore = savedInstanceState.getInt("TeamBScore");
        Log.i("Assign4", "Score values restored");
    }
    return rootview;
}

然后,EditText 字段已准备好在 onSaveInstanceState() 中使用,因此您可以删除对 findViewById() 的调用:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    setUserVisibleHint(false);

    savedInstanceState.putInt("TeamATry", TeamATry);
    savedInstanceState.putInt("TeamBTry", TeamBTry);
    //EditText teamAname = (EditText) mView.findViewById(R.id.teamAname);
    //teamAname.setInputType(InputType.TYPE_CLASS_TEXT);
    String teamAnametext = teamAname.getText().toString();
    //EditText teamBname = (EditText) mView.findViewById(R.id.teamBname);
    //teamBname.setInputType(InputType.TYPE_CLASS_TEXT);
    String teamBnametext = teamBname.getText().toString();
    savedInstanceState.putInt("TeamAConvert", TeamAConvert);
    savedInstanceState.putInt("TeamBConvert", TeamBConvert);
    savedInstanceState.putInt("TeamAPenalty", TeamAPenalty);
    savedInstanceState.putInt("TeamBPenalty", TeamBPenalty);
    savedInstanceState.putInt("TeamAScore", TeamAscore);
    savedInstanceState.putInt("TeamBScore", TeamBscore);
    savedInstanceState.putString("TeamAname", teamAnametext);
    savedInstanceState.putString("TeamBname", teamBnametext);
    super.onSaveInstanceState(savedInstanceState);
    Log.i("4", teamAnametext + "Saved");
    Log.i("4", "Match Frag Scores saved");
    super.onSaveInstanceState(savedInstanceState);
}

【讨论】:

  • 谢谢丹尼尔,我试过了,应用程序仍然在屏幕旋转时崩溃 java.lang.NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()'在指向 String teamAnametext = teamAname.getText().toString(); 的空对象引用上
  • @MarcusRey 这很奇怪。您可以将您的 rugbycounter.xml 文件添加到问题中吗?
  • 我已经添加了布局文件。奇怪的是,它在主片段/主片段的屏幕旋转时崩溃,但其他片段都没有。
  • @HarshitDwivedi 该示例不适用于这种情况,因为它正在从 Activity 中寻找布局 ID。
  • @HarshitDwivedi 只要片段的布局在onCreateView() 中正确膨胀并添加到视图树中,它实际上可以在onActivityCreated() 中调用getActivity().findViewById()。然而,真的没有理由让它过于复杂,因为直接在视图上使用findViewById() 会更干净。见这里:stackoverflow.com/questions/11385461/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2015-02-11
相关资源
最近更新 更多