将值保存到共享首选项后应用程序崩溃
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
参数是多余的,应该删除。
我正在尝试使用 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
参数是多余的,应该删除。