将值保存到共享首选项后应用程序崩溃

App is crashing after saving value to Shared Preferences

我正在尝试使用 Android Studio(使用 java)编写我的第一个应用程序,但卡住了。 该应用程序应从用户那里获取输入(使用纯文本),然后保留它并在下次启动该应用程序时显示它。 我希望能够在应用程序启动之间保留数据,据我所知,最有效和优雅的方法是使用共享首选项。但是每次我按下将文本保存到共享首选项的按钮时,应用程序都会崩溃。

这是我的代码:

public class FirstFragment extends Fragment {
    
    private final String PREFS = "sharedPrefs";
    private final String INPUT = "user_input";
    private final String MEMO = "memo";
    SharedPreferences sharedPreferences = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false);
    }

    private void saveData(View view) {
        TextView input = view.findViewById(R.id.user_input);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(MEMO, input.getText().toString());
        editor.apply();
    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        sharedPreferences = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);

        TextView memos = view.findViewById(R.id.memos);
        memos.setText(sharedPreferences.getString(MEMO, ""));

        view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                saveData(view);
            }
        });
    }

编辑:我的崩溃日志:

    Process: com.example.myfirstapplication, PID: 2322
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.TextView.getText()' on a null object reference
        at com.example.myfirstapplication.FirstFragment.saveData(FirstFragment.java:32)
        at com.example.myfirstapplication.FirstFragment.access[=11=]0(FirstFragment.java:14)
        at com.example.myfirstapplication.FirstFragment.onClick(FirstFragment.java:47)
        at android.view.View.performClick(View.java:7161)
        at android.view.View.performClickInternal(View.java:7138)
        at android.view.View.access00(View.java:811)
        at android.view.View$PerformClick.run(View.java:27419)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7520)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

很高兴看到是否有人能解决我的问题!

当您按下按钮时,您调用了 saveData() 方法。但是您将按钮视图设置为参数而不是根视图。你应该这样做

view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) { 
        // change onClick's parameter name from view to v
            saveData(view);
        }
    });

将您的 SharedPrefrence 对象的赋值添加为 Fragment 字段肯定会引发异常,因为它是在片段附加到您的 activity 之前调用的,并且就fragment lifecycle, the onAttach() 回调尚未调用,因此,getActivity() 将为空。

SharedPreferences sharedPreferences = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);

你得到的例外情况类似于:

java.lang.IllegalStateException: Fragment FirstFragment{cfb327} (a42392bd-ee02-48a2-9d61-aaa8c455bb10)} not attached to an activity.

要解决此问题,请替换下面的行

SharedPreferences sharedPreferences = getActivity().getSharedPreferences(PREFS, Context.MODE_PRIVATE);

SharedPreferences sharedPreferences;

并且您已经在 onViewCreated() 方法中对其进行了初始化。

使用调试器,您可以看到在 saveData 函数中,input 变量仍然是 Null。为了解决这个问题,替换:

TextView input = view.findViewById(R.id.user_input);

有:

TextView input = getActivity().findViewById(R.id.user_input);

您可以检查 input 的值以验证所需的字符串确实存在。

p.s。现在在函数中使用 view 参数是多余的,应该删除。