Значение Sharedpreference byte [] очищено после приложения, убитого через "Force Stop" или диспетчер задач

Проблема

Я сохраняю byte[] в своих общих настройках. Я могу закрыть приложение и снова открыть его со значением, сохраняющимся в общих настройках. При запуске приложения и закрытии его с помощью "Диспетчера задач" или "Принудительное закрытие" значение Shared Preference для byte[] очищается. Я не понимаю этого, потому что другие ценности сохраняются хорошо.

Это заставило меня поверить, что это связано с некоторыми проблемами с gson или Shared Preference с byte[], поэтому я преобразовал его в String, и у меня все еще есть проблема.

Edit:
Я сохраняю данные во время обычного использования активности... например, после onCreate(). Это не во время onPuse() или onDestroy() Я забыл упомянуть об этом. Было бы разумно, если бы я назвал его здесь, и один или оба из них не вызывались в сценарии "Сила закрытия".


Код общей привилегии

Немного изменен, чтобы удалить конкретную реализацию приложения и данные

private static final String SHARED_PREFERENCES_FILE_NAME = "SharedPreferenceName";

    public static void setSharedPreferenceObjectBase64Encoded(Context context, String key, Object object) throws Exception {
        // Need an editor to update shared preference values
        SharedPreferences.Editor editor = context.getSharedPreferences(SHARED_PREFERENCES_FILE_NAME, Context.MODE_PRIVATE).edit();
        Gson gson = new GsonBuilder().serializeNulls().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").create();
        String encodedKey = Base64.encodeToString(key.getBytes(), 0, key.getBytes().length, Base64.DEFAULT);
        String stringObject = gson.toJson(object);
        String encodedObject = Base64.encodeToString(stringObject.getBytes(), 0, stringObject.getBytes().length, Base64.DEFAULT);
        editor.putString(encodedKey, encodedObject);
        editor.apply();
    }

    public static Object getSharedPreferenceObjectBase64Encoded(Context context, String key, Class<? extends Serializable> objectClass) throws Exception {
        // Need an editor to update shared preference values
        SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_FILE_NAME, Context.MODE_PRIVATE);
        Gson gson = new GsonBuilder().serializeNulls().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").create();
        String encodedKey = Base64.encodeToString(key.getBytes(), 0, key.getBytes().length, Base64.DEFAULT);
        String encodedObject = prefs.getString(encodedKey, null);
        if (encodedObject == null) {
            throw new NullPointerException("encodedObject is null : No shared preference exists for key.");
        }
        String decodedObject = new String(Base64.decode(encodedObject, Base64.DEFAULT));
        if(decodedObject == null){
            throw new NullPointerException("decodedObject is null : Json decoding error.");
        }
        Object resultObject = gson.fromJson(decodedObject, objectClass);
        if (resultObject == null) {
            throw new NullPointerException("resultObject is null : Json decoding error.");
        }
        return resultObject;
    }

`byte []` Код

public static final String VALUE_KEY= "value.key";

    public static void saveTheValue(Context context, byte[] encryptedPin) {
        try {
            USharedPreferenceManager.setSharedPreferenceObjectBase64Encoded(context, VALUE_KEY, encryptedPin);
        } catch (Exception e) {
        }
    }

    public static byte[] getTheValue(Context context) {
        try {
            return (byte[]) USharedPreferenceManager.getSharedPreferenceObjectBase64Encoded(context, VALUE_KEY, byte[].class);
        } catch (Exception e) {
            return null;
        }
    }

Приветствуется любой ввод.

К сожалению, я не смог добиться какого-либо прогресса здесь. Любые мысли?


Обновление:

В соответствии с Super-califragilistic рекомендацией, я повторил через пары ключ/значение в SharedPreferences непосредственно перед извлечением значения. Я был Base64, кодирующий мои значения ключа и значения; чтобы прочитать ключ, чтобы убедиться, что значение было в SharedPreferences, которое мне пришлось использовать в текстовом виде. Это решило проблему для меня, так как значение byte[] теперь было правильно восстановлено.

Это кажется мне странным, но я могу использовать его в качестве решения. Я все равно хотел бы, чтобы Base64 закодировал ключи, но это не невероятно важно.


Текущее решение:

Удалена кодировка Base64 ключа SharedPreference для хранения и извлечения, и значение теперь сохраняется во всех случаях.

Ответ 1

Эта строка кода String encodedObject = prefs.getString(encodedKey, null); означает, что ключ не существует, он должен возвращать значение null, поэтому ваш ключ, который вы проверяете, не существует.

Чтобы проверить, существует ли ваш ключ/значение, используйте этот код

for(Entry<String, ?> en : sharedPref.getAll().entrySet()){
      en.getKey();//key
      en.getValue();//value
}

вы можете остановить это из override onPause() в Activity или Fragment и вызвать saveTheValue(Context context, byte[] encryptedPin), если вы обнаружите, что вам нужно сохранить данные или уже попытаться сохранить данные, например.

private boolean forceSaveInOnPause= false;//global variable

//in your saving method
....//after you save
forceSaveInOnPause = true;

//in your onPause of Activity
if(forceSaveInOnPause){       
   //re-save
   forceSaveInOnPause = false;

но поскольку у вас уже есть решение, почистите все это:)

Ответ 2

Попробуйте один раз с editor.commit() вместо apply(), посмотрите, работает ли это

Ответ 3

Я думаю, что использование Base64.NO_PADDING вместо Base64.DEFAULT, хотя чтение и запись могут решить проблему.