100 votes

Impossible de mettre un double SharedPreferences

Eclipse a donné une solution rapide en ajoutant le cast à l'éditeur, mais quand je fais cela, il donne toujours des erreurs, pourquoi je ne peux pas mettre le double.

Le code :

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();

    if (TextUtils.isEmpty(editBl.getText().toString())) {
        numberOfBl = 0;
    } else {
        numberOfBl = Integer.parseInt(editBl.getText().toString();

    }
    if (TextUtils.isEmpty(editSt.getText().toString())) {
        tonOfSt = 0;
    } else {
        tonOfSt = Double.parseDouble(editSt.getText().toString());

    }

    SharedPreferences prefs = getSharedPreferences(
            "SavedTotals", Context.MODE_PRIVATE);

    SharedPreferences.Editor editor = prefs.edit();

    editor.putInt("savedBl", numberOfBl);
    editor.putDouble("savedSt", tonOfSt);

    editor.commit();
}

359voto

copolii Points 2393

Ceux qui ont suggéré d'utiliser putFloat y getFloat ont malheureusement tout faux. Le transfert d'un double vers un flottant peut donner lieu à

  1. Précision perdue
  2. Débordement
  3. Débit inférieur
  4. Chatons morts

Ceux qui suggèrent une toString y parseString n'ont pas tort, mais c'est une solution inefficace.

La manière correcte de traiter cette situation est de convertir le double en son équivalent en "bits longs bruts" et de stocker ce long. Lorsque vous lisez la valeur, reconvertissez-la en double.

Comme les deux types de données ont la même taille, vous ne perdez pas en précision et ne provoquez pas de débordement {supérieur, inférieur}.

Editor putDouble(final Editor edit, final String key, final double value) {
   return edit.putLong(key, Double.doubleToRawLongBits(value));
}

double getDouble(final SharedPreferences prefs, final String key, final double defaultValue) {
return Double.longBitsToDouble(prefs.getLong(key, Double.doubleToLongBits(defaultValue)));
}

Alternativement, vous pouvez écrire le getter comme :

double getDouble(final SharedPreferences prefs, final String key, final double defaultValue) {
if ( !prefs.contains(key))
        return defaultValue;

return Double.longBitsToDouble(prefs.getLong(key, 0));
}

41voto

Dima Rostopira Points 3183

Extension Kotlin (beaucoup plus jolie que l'utilisation de classes utils bizarres ou autres).

fun SharedPreferences.Editor.putDouble(key: String, double: Double) =
    putLong(key, java.lang.Double.doubleToRawLongBits(double))

fun SharedPreferences.getDouble(key: String, default: Double) =
    java.lang.Double.longBitsToDouble(getLong(key, java.lang.Double.doubleToRawLongBits(default)))

19voto

John Points 191

Ce que j'ai fait, c'est enregistrer la préférence sous forme de chaîne :

getSharedPreferences("PREFERENCE", MODE_PRIVATE).edit().putString("double", "0.01").commit();

et ensuite, pour récupérer le double, il suffit d'utiliser Double.parseDouble :

Double.parseDouble(getSharedPreferences("PREFERENCE", MODE_PRIVATE).getString("double", "0.01"));

9voto

bprice Points 101

Vous pouvez toujours implémenter SharedPreferences et envelopper l'implémentation Android.

package com.company.sharedpreferences;

import android.content.Context;
import android.content.SharedPreferences;

import java.util.Map;
import java.util.Set;

public class EnhancedSharedPreferences implements SharedPreferences {

    public static class NameSpaces {
        public static String MY_FUN_NAMESPACE = "MyFunNameSpacePrefs";
    }

    public static EnhancedSharedPreferences getPreferences(String prefsName) {
        return new EnhancedSharedPreferences(SomeSingleton.getInstance().getApplicationContext().getSharedPreferences(prefsName, Context.MODE_PRIVATE));
    }

    private SharedPreferences _sharedPreferences;

    public EnhancedSharedPreferences(SharedPreferences sharedPreferences) {
        _sharedPreferences = sharedPreferences;
    }

    //region Overrides

    @Override
    public Map<String, ?> getAll() {
        return _sharedPreferences.getAll();
    }

    @Override
    public String getString(String key, String defValue) {
        return _sharedPreferences.getString(key, defValue);
    }

    @Override
    public Set<String> getStringSet(String key, Set<String> defValues) {
        return _sharedPreferences.getStringSet(key, defValues);
    }

    @Override
    public int getInt(String key, int defValue) {
        return _sharedPreferences.getInt(key, defValue);
    }

    @Override
    public long getLong(String key, long defValue) {
        return _sharedPreferences.getLong(key, defValue);
    }

    @Override
    public float getFloat(String key, float defValue) {
        return _sharedPreferences.getFloat(key, defValue);
    }

    @Override
    public boolean getBoolean(String key, boolean defValue) {
        return _sharedPreferences.getBoolean(key, defValue);
    }

    @Override
    public boolean contains(String key) {
        return _sharedPreferences.contains(key);
    }

    @Override
    public Editor edit() {
        return new Editor(_sharedPreferences.edit());
    }

    @Override
    public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
        _sharedPreferences.registerOnSharedPreferenceChangeListener(listener);
    }

    @Override
    public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
        _sharedPreferences.unregisterOnSharedPreferenceChangeListener(listener);
    }

    //endregion

    //region Extension

    public Double getDouble(String key, Double defValue) {
        return Double.longBitsToDouble(_sharedPreferences.getLong(key, Double.doubleToRawLongBits(defValue)));
    }

    //endregion

    public static class Editor implements SharedPreferences.Editor {

        private SharedPreferences.Editor _editor;

        public Editor(SharedPreferences.Editor editor) {
            _editor = editor;
        }

        private Editor ReturnEditor(SharedPreferences.Editor editor) {
            if(editor instanceof Editor)
                return (Editor)editor;
            return new Editor(editor);
        }

        //region Overrides

        @Override
        public Editor putString(String key, String value) {
            return ReturnEditor(_editor.putString(key, value));
        }

        @Override
        public Editor putStringSet(String key, Set<String> values) {
            return ReturnEditor(_editor.putStringSet(key, values));
        }

        @Override
        public Editor putInt(String key, int value) {
            return ReturnEditor(_editor.putInt(key, value));
        }

        @Override
        public Editor putLong(String key, long value) {
            return ReturnEditor(_editor.putLong(key, value));
        }

        @Override
        public Editor putFloat(String key, float value) {
            return ReturnEditor(_editor.putFloat(key, value));
        }

        @Override
        public Editor putBoolean(String key, boolean value) {
            return ReturnEditor(_editor.putBoolean(key, value));
        }

        @Override
        public Editor remove(String key) {
            return ReturnEditor(_editor.remove(key));
        }

        @Override
        public Editor clear() {
            return ReturnEditor(_editor.clear());
        }

        @Override
        public boolean commit() {
            return _editor.commit();
        }

        @Override
        public void apply() {
            _editor.apply();
        }

        //endregion

        //region Extensions

        public Editor putDouble(String key, double value) {
            return new Editor(_editor.putLong(key, Double.doubleToRawLongBits(value)));
        }

        //endregion
    }
}

1voto

Dezo Points 121

En Kotlin, vous pouvez convertir la valeur double en une représentation binaire de la valeur à virgule flottante spécifiée en tant que Long, puis enregistrer cette représentation binaire dans la préférence partagée avec putLong() méthode. Lorsque vous voulez récupérer cette valeur à partir de la préférence partagée, il suffit de la convertir en valeur Double avec la méthode Double.fromBits() et vous obtiendrez une valeur double sans perte de précision. Vous pouvez en savoir plus à ce sujet aquí .

Voici un exemple où j'utilise la latitude et la longitude comme une double valeur dans une préférence partagée :

    val lat: Double = 40.23244412709637
    val lng: Double = 14.280891281901097

     private fun saveFetchedLocation(lat: Double, lng: Double) {
            val sharedPreference: SharedPreferences = requireActivity().getSharedPreferences(
                SHARED_PREF,
                Context.MODE_PRIVATE
            )
            val editor: SharedPreferences.Editor = sharedPreference.edit()
            editor.apply {
                putLong("lat_value", lat.toBits())
                putLong("lng_val", lng.toBits())

            Log.i("Tag", "LONG_BITS: "+ " Lat: " + lat.toBits() + " Lng: " + lng.toBits())

            }.apply()

        }

    private fun loadPreferences() {
            val sharedPreference: SharedPreferences = requireActivity().getSharedPreferences(
                SHARED_PREF,
                Context.MODE_PRIVATE
            )
            val lat_double: Double = Double.fromBits(sharedPreference.getLong("lat_value", 1))
            val lng_double: Double = Double.fromBits(sharedPreference.getLong("lng_val", 1))

            Log.i("Tag", "FINAL_DOUBLE: $lat_double and $lng_double")

        }

Résultat du logcat :

//bit representation of the specified floating-point values as Long
I/Tag: LONG_BITS:  Lat: 4630859030446343002 Lng: 4624229045136719443 

//converted double values with no precision loss
I/Tag: FINAL_DOUBLE: 40.23244412709637 and 14.280891281901097

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X