이중 SharedPreferences를 넣을 수 없습니다.


90

오류가 발생하면이 유형의 sharedPreferences 편집기에 대해 put double 메소드가 정의되어 있지 않습니다 .Eclipse는 편집기에 캐스트를 추가하는 빠른 수정이 제공되지만 여전히 오류가 발생하면 왜 두 번 넣을 수 없습니까?

코드:

@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();
}

2
어떤 오류가 있는지 지정해 주시겠습니까?
dumbfingers

1
질문의 첫 번째 줄을보십시오
Robert

어떻게 안드로이드 사람들이 API에서 putDouble을 구현하지 않았는지 궁금합니다.
luky

답변:


337

putFloatgetFloat 사용을 제안한 사람들 은 불행히도 매우 잘못되었습니다. double을 float로 캐스팅하면

  1. 잃어버린 정밀도
  2. 과다
  3. 언더 플로
  4. 죽은 새끼 고양이

toStringparseString을 제안하는 것은 잘못된 것은 아니지만 비효율적 인 솔루션입니다.

이를 처리하는 올바른 방법은 double을 'raw long bits'등가물로 변환하고 해당 long을 저장하는 것입니다. 값을 읽을 때 다시 double로 변환하십시오.

두 데이터 유형의 크기가 같기 때문에 정밀도를 잃지 않고 {over, under} 흐름이 발생하지 않습니다.

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)));
}

또는 getter를 다음과 같이 작성할 수 있습니다.

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

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

9
너무 아름답고 깨끗하고 우아합니다.
Bogdan Alexandru

9
putDouble 메소드는 Android 생태계 내의 다른 API (예 : parceable 및 bundles) 와도 여전히 훌륭하고 일관성이 있습니다. Google이 다시 빠르고 엉성한 전형적인 경우입니다.

2
문자열로 저장하는 것이 비효율적 인 이유는 무엇입니까?
KKO

2
@KKO long 데이터 유형은 64 비트 2의 보수 정수입니다. 따라서 4 바이트 만 필요합니다. 그러나 그 double값을 문자열로 저장하면 저장소가 망가 져서 잔해가됩니다 !!
semsamot 2014 년

1
prefs.getLong (key, 0d) 부정확하며 double이 아닙니다. d가 없어야합니다.
Ahmed Hegazy 2014

28

Kotlin 확장 방식 (이상한 유틸리티 클래스 등을 사용하는 것보다 훨씬 더 예쁘다)

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)))

2
좋아, 나는 이것을 여기에 넣는 것에 대해 정확히 생각하고 있었다. 감사!
wzieba

16

내가 한 일은 환경 설정을 문자열로 저장하는 것입니다.

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

그런 다음 double을 검색하려면 Double.parseDouble을 사용하십시오.

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

4
스토리지를 낭비하고 있습니다. 또한 doubleToRawLongBits이미 언급 한 방법 보다 훨씬 느립니다 . 이것은 작동하지 않기 때문이 아니라 매우 비효율적이기 때문에 잘못된 방법입니다.
copolii 2014

10
@copolii 학술적으로는 물론입니다. 실제로 업계에서는 99 %의 사례에서 문제에 대한 충분한 차이를 만들지 못하며 실제로 이것은 새로운 사람을 데려 올 때 더 읽기 쉽고 이해하기 쉽습니다.
Dennis L

@DennisL #PracticalDev
아바

9

항상 SharedPreferences를 구현하고 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
    }
}

이것이 정답입니다. 나는 타이핑을 시작하기 전에 이것을 보았다면 좋겠다. 편집기 메서드에서 'this'를 반환하는 것이 더 효율적이지 않을까요? 'instanceof'메서드를 호출하지 않아도됩니다. 아니면 그것을 시도하고 문제를 일으켰습니까?
copolii

0

이 요점을 확인하십시오 https://gist.github.com/john1jan/b8cb536ca51a0b2aa1da4e81566869c4

모든 경우를 처리 할 Preference Utils 클래스를 만들었습니다.

사용하기 쉽습니다.

기호에 저장

PrefUtils.saveToPrefs(getActivity(), PrefKeys.USER_INCOME, income);

선호도에서 얻기

Double income = (Double) PrefUtils.getFromPrefs(getActivity(), PrefKeys.USER_INCOME, new Double(10));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.