【问题标题】:SharedPreferences return nullSharedPreferences 返回 null
【发布时间】:2016-08-17 15:34:57
【问题描述】:

我知道之前问过几个类似的问题,但是尽管按照建议的解决方案进行了所有操作,但我的 sharedPreferences 仍然返回空值。以下是我的代码:

我在 MainActivity 中声明了 2 个静态方法,用于从如下所示的整个应用程序访问 sharedPrefences。

  public static void saveToPreferences(Context context, int i,String key) {
        mSharedPreferences = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = mSharedPreferences.edit();
        editor.putInt(key , i);
        //used in place of commit as it is faster. This does the task asynchronously
        editor.commit();
    }

    public static int readFromPreferences(Context context, int i, String key) {
        mSharedPreferences = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        int fed_value = mSharedPreferences.getInt(key, i);
        return fed_value;
    }

我正在从另一种方法访问这些值,如下所示

      static PendingIntent pendingIntent;
      static Intent alarmIntent;
      int mMinute;
      final Calendar calendar = Calendar.getInstance();
      int mCurrentHour = calendar.get(calendar.HOUR_OF_DAY);
      int mCurrentMinute = calendar.get(calendar.MINUTE);
      int minuteDifference;
        int mHour;
// Create the TimePicker
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            return new TimePickerDialog(getActivity(), this, mCurrentHour, mCurrentMinute,
                    DateFormat.is24HourFormat(getActivity()));
        }

        @Override
        public void onTimeSet(android.widget.TimePicker view, int hourOfDay, int minute) {
            mHour = hourOfDay;
            minuteDifference = Math.abs(mCurrentMinute - mMinute);
            MainActivity.saveToPreferences(getActivity(),minuteDifference,"set_minute");
            mMinute = minute;
            MainActivity.saveToPreferences(getActivity(), Math.abs(mCurrentHour - mHour), "set_hour");


        public int minuteDifference(){
            Log.d("tag", String.valueOf(mHour) + " " + String.valueOf(mMinute));
            return  MainActivity.readFromPreferences(getActivity(),minuteDifference,"set_minute");
        }
        public int HourDifference(){
            return MainActivity.readFromPreferences(getActivity(),Math.abs(mCurrentHour - mHour),"set_hour");
        }

方法 minuteDifference 返回 null。它是从一个单独的片段中调用的,如下面的 onStart 方法所示。以下是流程的工作原理:

点击按钮(下面代码块中的 setTime.setOnclickListener(..) )显示 timePicker,然后调用 onTimeSet 方法将数据保存到首选项。

第二个按钮的点击(setAlarm.setOnClickListener(..) 在下面的代码块中)调用方法 minuteDifference 方法,该方法在上面显示的单独片段中定义。

这应该从 sharedPreferences 中读取所需的值并返回它。但它返回 null

@Override
    public void onStart() {
        super.onStart();
        final Button setTime = (Button) getActivity().findViewById(R.id.set_time);
        final Button setAlarm = (Button) getActivity().findViewById(R.id.set_alarm);
        alarmIntent = new Intent(getActivity(), AlarmReciever.class);
        pendingIntent = PendingIntent.getBroadcast(getActivity(), 0, alarmIntent, 0);
        setAlarm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlarmManager manager;
                TimePickerFragment tfSchedule = new TimePickerFragment();
                int mDifferenceMinute = tfSchedule.minuteDifference();
                manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
                int interval = mDifferenceMinute*60000;
                Log.d("minuteDifference",String.valueOf(mDifferenceMinute));
//                manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
                manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                        SystemClock.elapsedRealtime() +
                                interval, pendingIntent);

            }
        });

        setTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TimePickerFragment tfViewTimer = new TimePickerFragment();
                tfViewTimer.show(getFragmentManager(), "Tag");

                }

        });
    } 

以下是错误日志

08-17 10:05:47.525 25850-25850/com.rs.rishitshah.feedingnemo E/AndroidRuntime: 致命异常: main 进程:com.rs.rishitshah.feedingnemo,PID:25850 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' 在 com.rs.rishitshah.feedingnemo.MainActivity.readFromPreferences(MainActivity.java:265) 在 com.rs.rishitshah.feedingnemo.TimePickerFragment.minuteDifference(TimePickerFragment.java:63) 在 com.rs.rishitshah.feedingnemo.ScheduleFeed$1.onClick(ScheduleFeed.java:51) 在 android.view.View.performClick(View.java:5204) 在 android.view.View$PerformClick.run(View.java:21155) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5422) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

PS:在将此问题标记为重复或否决此问题之前,请注意我遵循以下链接并且已经按照其中提到的解决方案获得了我的代码。尽管如此,我的代码仍然无法正常工作。

android - sharedpreferences return null value

SharedPreferences getString returns null though set by editor in AsyncTask

SharedPreferences returns null values

Sharedpreferences in Android returns null when called from another activity

【问题讨论】:

标签: java android android-fragments


【解决方案1】:

问题在于这些行处的片段;

            TimePickerFragment tfSchedule = new TimePickerFragment();
            int mDifferenceMinute = tfSchedule.minuteDifference();

没有Context(它没有附加到Activity)。更具体地说,Contextnull

您应该知道Fragments 在附加之前没有Context,并且(也许更重要)您应该避免在其中使用这样的静态方法。您应该创建一个时间对象,或者,由于您使用的是SharedPreferences,因此只需创建一个辅助对象,当您从中调用“设置”或“获取”数据时传入Context

【讨论】:

  • 感谢您的回答。但我有个问题。如果是这种情况,在调用 saveToPreferences 时不应该抛出相同的异常吗?
  • 由于您没有发布完整的代码,我会假设因为直到片段附加后才进行调用(保存听起来像是在显示后发生的事情 - 这意味着片段已附加)
  • 使用应用程序上下文解决了这个问题。谢谢
【解决方案2】:

您的共享偏好没有返回 null。您的上下文为空。这是因为您使用 new 创建了一个片段,不将其添加到任何布局中,然后在其上调用一个方法。它没有 Activity,因为它没有通过 Transaction 添加到任何布局中。看起来你在滥用碎片。这些功能不应该存在于片段上,它们应该存在于其他地方。可能在您从或在助手类中调用它的活动中。如果您不打算将片段添加到布局中,则不应使用片段来访问辅助函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多