更改时,SharedPreferences不会触发onStart

时间:2016-07-28 15:21:53

标签: android sharedpreferences

我已经编写了一个用于从USGS获取地震数据的应用程序,我想为想要检查不同mag级别的用户添加首选项更改。但是,当首选项发生更改时,onStart不会触发。请建议我如何修改代码

public class EarthquakeFragment extends Fragment{
public EarthquakeFragment(){
}

ListView listView;
private EarthquakeAdapter eAdapter;

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState)
{
    View rootView = inflater.inflate(R.layout.earthquake_fragment, container, false);

    eAdapter = new EarthquakeAdapter(getActivity(), new ArrayList<EarthquakeInfo>());
    listView = (ListView) rootView.findViewById(R.id.list);
    listView.setAdapter(eAdapter);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            EarthquakeInfo currentEarthquake = eAdapter.getItem(position);
            String url = currentEarthquake.getUrl();

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse(url));
            startActivity(intent);
        }
    });
    setHasOptionsMenu(true);
    // Start the AsyncTask to fetch the earthquake data
    EarthquakeAsyncTask task = new EarthquakeAsyncTask();
    task.execute();
    return rootView;
}


/**
 * {@link AsyncTask} to perform the network request on a background thread, and then
 * update the UI with the list of earthquakes in the response.
 *
 * AsyncTask has three generic parameters: the input type, a type used for progress updates, and
 * an output type. Our task will take a String URL, and return an Earthquake. We won't do
 * progress updates, so the second generic is just Void.
 *
 * We'll only override two of the methods of AsyncTask: doInBackground() and onPostExecute().
 * The doInBackground() method runs on a background thread, so it can run long-running code
 * (like network activity), without interfering with the responsiveness of the app.
 * Then onPostExecute() is passed the result of doInBackground() method, but runs on the
 * UI thread, so it can use the produced data to update the UI.
 */
private class EarthquakeAsyncTask extends AsyncTask<String, Void, List<EarthquakeInfo>> {

    /**
     * This method runs on a background thread and performs the network request.
     * We should not update the UI from a background thread, so we return a list of
     * {@link EarthquakeInfo}s as the result.
     */
    @Override
    protected List<EarthquakeInfo> doInBackground(String... urls) {


        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        String maglevel = preferences.getString(getString(R.string.pref_mag_key), "");

            final String BASE_URL= "http://earthquake.usgs.gov/fdsnws/event/1/query?";
            final String FORMAT_PARAM = "format";
            final String ORDER_PARAM = "orderby";
            final String START_PARAM = "starttime";
            final String END_PARAM = "endtime";
            final String MINMAG_PARAM = "minmag";
            String format = "geojson";
            String order = "time";
            String start = "2016-01-01";
            String end = "2016-07-28";
            String minmag = maglevel;

            Uri buildUri = Uri.parse(BASE_URL).buildUpon()
                    .appendQueryParameter(FORMAT_PARAM, format)
                    .appendQueryParameter(ORDER_PARAM, order)
                    .appendQueryParameter(START_PARAM, start)
                    .appendQueryParameter(END_PARAM, end)
                    .appendQueryParameter(MINMAG_PARAM, minmag)
                    .build();
            String url = buildUri.toString();


        // Don't perform the request if there are no URLs, or the first URL is null.
        if (url == null) {
            return null;
        }

        List<EarthquakeInfo> result = QueryUtils.fetchEarthquakeData(url);
        return result;
    }

    /**
     * This method runs on the main UI thread after the background work has been
     * completed. This method receives as input, the return value from the doInBackground()
     * method. First we clear out the adapter, to get rid of earthquake data from a previous
     * query to USGS. Then we update the adapter with the new list of earthquakes,
     * which will trigger the ListView to re-populate its list items.
     */
    @Override
    protected void onPostExecute(List<EarthquakeInfo> data) {
        // Clear the adapter of previous earthquake data
        onStart();
        eAdapter.clear();

        // If there is a valid list of {@link Earthquake}s, then add them to the adapter's
        // data set. This will trigger the ListView to update.
        if (data != null && !data.isEmpty()) {
            eAdapter.addAll(data);
        }
    }
}
}

非常感谢!!!!!

2 个答案:

答案 0 :(得分:0)

收听SharedPreferences上的更改无效。

为此,您需要实施SharedPreferences.OnSharedPreferenceChangeListener

SharedPreferences.OnSharedPreferenceChangeListener spChanged = new
                           SharedPreferences.OnSharedPreferenceChangeListener() {
            @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
            String key) {
        // your stuff here
    }
};

PreferenceActivity中,即将其设为PreferenceActivity课程的成员,然后在registerOnSharedPreferenceChangeListener(spChanged)方法中PreferenceActivity.onCreate()

答案 1 :(得分:0)

我终于解决了这个问题。

我在onResume上调用fetch数据方法。由于我无法在AsyncTask上获取空数据,因此会导致NullPointExection。所以我使用默认URL来执行AsyncTask。之后,我在onResume上添加了SharePreference。之后问题就解决了。

这是我的代码。

public class EarthquakeFragment extends Fragment{

public EarthquakeFragment(){
}

ListView listView;
EarthquakeAdapter eAdapter;

@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState)
{
    String defaultUrl = getActivity().getString(R.string.default_link);

    View rootView = inflater.inflate(R.layout.earthquake_fragment, container, false);

    eAdapter = new EarthquakeAdapter(getActivity(), new ArrayList<EarthquakeInfo>());
    listView = (ListView) rootView.findViewById(R.id.list);
    listView.setAdapter(eAdapter);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            EarthquakeInfo currentEarthquake = eAdapter.getItem(position);
            String url = currentEarthquake.getUrl();

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse(url));
            startActivity(intent);
        }
    });
    setHasOptionsMenu(true);
    // Start the AsyncTask to fetch the earthquake data
    EarthquakeAsyncTask task = new EarthquakeAsyncTask();
    task.execute(defaultUrl);
    return rootView;
}

private void updateEarthquake() {
    EarthquakeAsyncTask earthquakeTask = new EarthquakeAsyncTask();
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
    String maglevel = preferences.getString(getString(R.string.pref_mag_key), getString(R.string.pref_mag_6));
    String startTime = preferences.getString(getString(R.string.start_key), getString(R.string.pref_time_2016));
    String sortby= preferences.getString(getString(R.string.sort_key), getString(R.string.pref_sortby_time));

    final String BASE_URL= "http://earthquake.usgs.gov/fdsnws/event/1/query?";
    final String FORMAT_PARAM = "format";
    final String ORDER_PARAM = "orderby";
    final String START_PARAM = "starttime";
    final String END_PARAM = "endtime";
    final String MINMAG_PARAM = "minmag";
    final String LIMIT_PARAM = "limit";
    final String format = "geojson";
    final String order = sortby;
    String start = startTime+"-01-01";
    String end = startTime+"-12-31";
    String minmag = maglevel;
    final String limit = "10";

    Uri buildUri = Uri.parse(BASE_URL).buildUpon()
            .appendQueryParameter(FORMAT_PARAM, format)
            .appendQueryParameter(ORDER_PARAM, order)
            .appendQueryParameter(START_PARAM, start)
            .appendQueryParameter(END_PARAM, end)
            .appendQueryParameter(MINMAG_PARAM, minmag)
            .appendQueryParameter(LIMIT_PARAM, limit)
            .build();
    String url = buildUri.toString();

    // Don't perform the request if there are no URLs, or the first URL is null.
    if (url == null) {
    }
    earthquakeTask.execute(url);
}

@Override
public void onResume(){
    super.onResume();
    updateEarthquake();
}

/**
 * {@link AsyncTask} to perform the network request on a background thread, and then
 * update the UI with the list of earthquakes in the response.
 *
 * AsyncTask has three generic parameters: the input type, a type used for progress updates, and
 * an output type. Our task will take a String URL, and return an Earthquake. We won't do
 * progress updates, so the second generic is just Void.
 *
 * We'll only override two of the methods of AsyncTask: doInBackground() and onPostExecute().
 * The doInBackground() method runs on a background thread, so it can run long-running code
 * (like network activity), without interfering with the responsiveness of the app.
 * Then onPostExecute() is passed the result of doInBackground() method, but runs on the
 * UI thread, so it can use the produced data to update the UI.
 */
private class EarthquakeAsyncTask extends AsyncTask<String, Void, List<EarthquakeInfo>> {

    /**
     * This method runs on a background thread and performs the network request.
     * We should not update the UI from a background thread, so we return a list of
     * {@link EarthquakeInfo}s as the result.
     */
    @Override
    protected List<EarthquakeInfo> doInBackground(String... urls) {

        List<EarthquakeInfo> result = QueryUtils.fetchEarthquakeData(urls[0]);
        return result;
    }

    /**
     * This method runs on the main UI thread after the background work has been
     * completed. This method receives as input, the return value from the doInBackground()
     * method. First we clear out the adapter, to get rid of earthquake data from a previous
     * query to USGS. Then we update the adapter with the new list of earthquakes,
     * which will trigger the ListView to re-populate its list items.
     */
    @Override
    protected void onPostExecute(List<EarthquakeInfo> data) {
        // Clear the adapter of previous earthquake data
        eAdapter.clear();
        // If there is a valid list of {@link Earthquake}s, then add them to the adapter's
        // data set. This will trigger the ListView to update.
        if (data != null && !data.isEmpty()) {
            eAdapter.addAll(data);
        }
    }
}
}

这是我的设定活动代码

public class SettingActivity extends PreferenceActivity
    implements Preference.OnPreferenceChangeListener{

@Override
public void onCreate (Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.pref_general);

    bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_mag_key)));
    bindPreferenceSummaryToValue(findPreference(getString(R.string.start_key)));
    bindPreferenceSummaryToValue(findPreference(getString(R.string.sort_key)));

}

private void bindPreferenceSummaryToValue(Preference preference) {
    preference.setOnPreferenceChangeListener(this);
    onPreferenceChange(preference,
            PreferenceManager
                    .getDefaultSharedPreferences(preference.getContext())
                    .getString(preference.getKey(), ""));

}

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    String stringValue = newValue.toString();
    if (preference instanceof ListPreference) {
        ListPreference preferences = (ListPreference) preference;
        int prefIndex = preferences.findIndexOfValue(stringValue);
        if (prefIndex >= 0) {
            preference.setSummary(preferences.getEntries()[prefIndex]);
        }else {
            preference.setSummary(stringValue);
        }
    }
    return true;
}
}

希望它可以帮助任何面临同样问题的人。还请告知是否有任何&#34;不良原因&#34;获取onResume中的数据。

感谢您的回复!!!!!!