【问题标题】:Trying to use sharedPreferences, but the app crashes尝试使用 sharedPreferences,但应用程序崩溃
【发布时间】:2018-04-06 15:56:02
【问题描述】:

我正在尝试使用 sharedPreferences 以了解它们的工作原理。我有一个日期选择器并想要以下内容: 当应用程序第一次打开时,日期选择器会出现并且有人选择一个日期。之后,日期将被存储,然后每次打开应用程序时都会有一个 textView 显示日期,而不会再次出现日期选择器。另外,我希望保存日期以供将来参考。

这是我的代码:

主类

private TextView mDisplayDate;
DialogFragment bday = new BdayPick();
public static final String TAG = "main_date";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mDisplayDate = findViewById(R.id.tvDate);
    }

@SuppressLint({"SetTextI18n", "ApplySharedPref"})
@Override
protected void onResume() {
    super.onResume();
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
    boolean previouslyStarted = prefs.getBoolean(getString(R.string.pref_previously_started), false);
    if (!previouslyStarted) {
        SharedPreferences.Editor edit = prefs.edit();
        edit.putBoolean(getString(R.string.pref_previously_started), Boolean.TRUE);
        edit.commit();
        bday.show(getSupportFragmentManager(), "datePicker");
    } else setDateChosen();
}

@SuppressLint("SetTextI18n")
private void setDateChosen() {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        int day = prefs.getInt(String.valueOf(selected_day), 0);
        int year = prefs.getInt(String.valueOf(selected_year), 0);
        String month = prefs.getString(String.valueOf(selected_month), "0");
        Log.d(TAG, day + " / " + month + " / " + year);
        mDisplayDate.setText("The Selected date is: " + day + "-" + month + "-" + year);
}

选择器类

public class BdayPick extends DialogFragment
                            implements DatePickerDialog.OnDateSetListener {

   // Context context = getActivity();
    SharedPreferences sharedPrefs = getActivity().getPreferences(Context.MODE_PRIVATE);
@NonNull
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public Dialog onCreateDialog (Bundle savedInstanceState) {
    final Calendar cal = Calendar.getInstance();
    int year = cal.get(Calendar.YEAR);
    int month = cal.get(Calendar.MONTH);
    int day = cal.get(Calendar.DAY_OF_MONTH);

    return new DatePickerDialog(Objects.requireNonNull(getActivity()),
            android.R.style.Theme_Holo_Dialog,
            this,
            year, month, day);
}

@SuppressLint("StringFormatInvalid")
public void onDateSet(DatePicker view, int year, int month, int day) {
    //TODO calculate and show required textl
    month = month + 1;
    String date = day + "-" + month + "-" + year;

    SharedPreferences.Editor editor = sharedPrefs.edit();
    editor.putInt(getString(R.string.selected_day), day);
    editor.putString(getString(R.string.selected_month), String.valueOf(month));
    editor.putInt(getString(R.string.selected_year), year);
    editor.apply();

    Toast.makeText(getActivity(), date, Toast.LENGTH_LONG).show();
}
}

我没有构建或编译错误,但是当我尝试打开应用程序时它只是崩溃了,我不明白为什么。

**编辑: Logcat 解决了这个问题。我已经根据答案进行了编辑:

public void onDateSet(DatePicker view, int year, int month, int day) {
        month = month + 1;
        String date = day + "-" + month + "-" + year;

        SharedPreferences.Editor editor = sharedPrefs.edit();
        /*editor.putInt(getContext().getResources().getString(R.string.selected_day), day);
        editor.putString(getContext().getResources().getString(R.string.selected_month), String.valueOf(month));
        editor.putInt(getContext().getResources().getString(R.string.selected_year), year);
        editor.apply();
        */

    Calendar cal;
    cal= Calendar.getInstance().set(view.getYear(), view.getMonth(), view.getDayOfMonth());
    Date d = cal.getTime();
    PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString("pref_date", new SimpleDateFormat("ddMMyyyy").format(d));
    //editor.putString("date", new SimpleDateFormat("ddMMyyyy").format(c.getTime()));
        editor.apply();

    Toast.makeText(getActivity(), date, Toast.LENGTH_LONG).show();
    }

但现在我有以下错误:

incompatible types: void cannot be converted to Calendar

【问题讨论】:

  • 检查logcat并查看错误
  • 您发布的日志与崩溃无关
  • 不确定在这种情况下我应该添加什么日志。
  • 在日志中搜索“异常”。然后在这里发布。
  • 这个? '04-06 16:19:23.842 1693-1715/system_process E/KernelUidCpuFreqTimeReader: 无法读取 /proc/uid_time_in_state: java.io.FileNotFoundException: /proc/uid_time_in_state(没有这样的文件或目录)'

标签: android datepicker sharedpreferences


【解决方案1】:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.support.v4.app.FragmentActivity.getPreferences(int)' on a null object reference
  at com.example.zodiac.zodiac.BdayPick.<init>(BdayPick.java:23)

您在此处调用 getPreferences() 为 null:

SharedPreferences sharedPrefs = getActivity().getPreferences(Context.MODE_PRIVATE);

其中&lt;init&gt; 表示正在初始化对象,在这种情况下使用字段 init。 &lt;init&gt; 对于 getActivity() 来说返回除 null 以外的任何内容还为时过早 - 该片段尚未附加到任何活动。

您需要将需要Context 的代码移至稍后阶段,onAttach()fragment lifecycle 中的更高版本。

【讨论】:

  • 如果我不使用片段怎么办?在尝试使用 this.getPreferences(Context.MODE_PRIVATE) 时,我在主要活动上遇到类似的空错误
  • 您不能在onCreate() 之前将活动用作上下文。 &lt;init&gt; 也太早了。
【解决方案2】:

在主类中将 edit.commit(); 更改为 edit.apply();

并且还使用putBoolean(..., true) 而不是putBoolean(..., Boolean.TRUE)

**编辑: 不要在 SharedPrefernece 中使用字符串资源。改用常量字符串。 您可以尝试使用日期格式,例如:

f.e.:

Calendar c = Calendar.getInstance().set(view.getYear(), view.getMonth(), view.getDayOfMonth());
Date d = c.getTime();
PreferenceManager.getDefaultSharedPreferences(getAppliactionContext()).edit().putString("pref_date", new SimpleDateFormat("ddMMyyyy").format(d));

并使用以下方法读取值:

try {
    Date d = new SimpleDateFormat("ddMMyyyy").parse(PreferenceManager.getDefaultSharedPreferences(getAppliactionContext()).getString("pref_date", ""));

    //DO SOMETHING WITH THE VALUE
}
catch (ParseException e){
    Log.e("PreferenceRead ", e.getMessage());
}

【讨论】:

  • 试过了。仍然崩溃。
  • 所以发布您的完整 LogCat。不只是几行。
  • 试过这个,但我收到错误不兼容类型:void 无法转换为日历
【解决方案3】:

你的问题在那里:

SharedPreferences sharedPrefs = getActivity().getPreferences(Context.MODE_PRIVATE);

您可以改用:SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());

如果你不想使用默认的 SharedPreferences,你可以使用getActivity().getPreferences("name", Context.MODE_PRIVATE);,但我建议你使用默认的。

【讨论】:

    猜你喜欢
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多