Имея класс, который ссылается на значение ресурса для String и Drawable, мне нужно сохранить этот класс и загрузить его в будущем. Я настаиваю на GSON и общих настройках.

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

Как я могу избежать этой проблемы? Мне нужно сохранить этот класс ..

Это минимальный образец кода класса, который я настаиваю:

public class SpaceshipUpdate {
    private int nameResource;
    private int imageResource;

    public SpaceshipUpdate(int nameResource, int imageResource){
        this.nameResource = nameResource;
        this.imageResource = imageResource;
    }
}

И как я создаю новый экземпляр этого класса:

SpaceshipUpdate u1 = new SpaceshipUpdate(R.string.laser1_title, R.drawable.shop_proton_laser);
0
NullPointerException 14 Окт 2019 в 13:13

2 ответа

Вы можете сохранить имя ресурсов (например, «laser1_title») как строку вместо версии R.string.laser1_title и использовать эту вспомогательную функцию (или что-то подобное) для динамического получения этого ресурса.

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

public static int has_resource_id(Context context,String name,String resource_type)
{
    final int resourceId = context.getResources().getIdentifier(name, resource_type,
            context.getApplicationContext().getPackageName());
    return resourceId;
}
1
touhid udoy 14 Окт 2019 в 13:22
1
Проблема этого решения заключается в том, что вам нужно жестко закодировать имя ресурса или использовать аналогичную функцию, чтобы получить имя ресурса для ссылки на него. Так что это очень медленно для установки и получения ресурса, а для игры очень плохо использовать медленные решения.
 – 
NullPointerException
14 Окт 2019 в 13:26
Если вы действительно хотите что-то «сохранить», у вас должен быть «ключ», который не меняется. Итак, почему "жестко запрограммировать имя ресурса" является проблемой, я не совсем уверен. Что касается проблемы с производительностью, я согласен. Но я использовал этот подход в настраиваемом приложении календаря, где мне нужно было отображать 30 дней, каждый день был настраиваемым представлением с множеством функций. Таким образом я получил ресурсы. Я не заметил там такого большого отставания после относительно медленного запуска по сравнению с несколькими приложениями.
 – 
touhid udoy
14 Окт 2019 в 13:52
1
Я подумаю, используя это решение, спасибо
 – 
NullPointerException
14 Окт 2019 в 14:15
1
Я разместил свое решение, пожалуйста, вы можете взглянуть на него и высказать свое мнение?
 – 
NullPointerException
15 Окт 2019 в 12:22

Наконец, я выбрал это решение, вместо того, чтобы хранить созданные мной методы идентификатора ресурса в базовых классах, которые возвращают значение, зависящее от типа класса-потомка:

public int getName() {
    switch (type){
        case SPACESHIP_TYPE_1:
            return R.string.spaceship1;
        case SPACESHIP_TYPE_2:
            return R.string.spaceship2;
        case SPACESHIP_TYPE_3:
            return R.string.spaceship3;
        case SPACESHIP_TYPE_4:
            return R.string.spaceship4;
    }
    return -1;
}

Это не обязательно для хранения идентификатора ресурса.

0
NullPointerException 15 Окт 2019 в 12:20
Да, это действительный обходной путь. Но рассмотрим случай в игре, где у вас есть 10 типов космических кораблей, 50 типов людей, сотни объектов. Когда вы обращаетесь к ресурсам таким образом, 1. if проверяет каждый case внутри switch, пока не будет найдено совпадение. если есть МНОГО вариантов, это может быть даже медленнее, чем я предлагаю. 2. когда у вас есть МНОГО вариантов, это подвержено ошибкам, вам нужно написать МНОЖЕСТВО случаев, которые почти одинаковы. Пример: для 89-го объекта return R.string.object_no_89 перед аналогичными 88 строками, что НАМНОГО труднее отлаживать и содержит МНОГО почти повторяющегося кода.
 – 
touhid udoy
15 Окт 2019 в 12:43
Да, это правда, может быть быстрее, но может быть и медленнее, работает только для ситуаций с потерянными вариантами
 – 
NullPointerException
15 Окт 2019 в 21:31