Я пытаюсь создать многоразовый класс на Android, который извлекает данные пользователей из базы данных Firebase, создает список моделей пользователей и возвращает этот список любым другим классам, которым может понадобиться этот список. Но я не могу этого сделать. Я не буду утомлять вас всем кодом, но в основном я получил следующее:
Class Reusable {
//declare FireBase Auth, DatabaseReference, etc.
private Context mContext;
private List<Users> mUserList;
public Reusable (Context context){
mContext = context;
mUserList= new ArrayList<>();
}
}
public void getUsersIdFromDb(){
List<Strings> idList = = new ArrayList<>();
//gets Users Id from Database and save it to idList:
idList.addAll(ids); //ids are ids fetched from Database
Log.d("StepOne",Integer.toString(idList.size(); //returns correct number of ids
createListOfModels(idList);
}
private void createListOfModels(final List<Strings> list){
//compares fetched ids with ids inside logged user node
//if it passes:
for(String id: list){
String name = datasnapshot.child(id).child("name).getValue();
String pic= datasnapshot.child(id).child("pic).getValue();
UserModel user = new UserModel(name, pic);
mUserList.add(user);
}
processListOfUsers(mUserList);
}
private void processListOfUsers(List<Users> list){
for (User u: list){
mUserList.add(u);
Set<Users> hs = new LinkedHashSet<>();
hs.addAll(mUserList);
mUserList.clear();
mUserList.addAll(hs);
Log.d("StepThree",Integer.toString(mUserList.size(); //returns correct number of Users
}
}
public List<Users> getList(){
return mUserList;
}
Затем при вызове класса Reusable:
public SomeClass extends AppCompatActivity {
//onCreate, etc...
Reusable reusable = new Reusable(SomeClass.this);
reusable.getUsersIdFromDb();
int i = reusable.getList().size();
Log.d("FromSomeClass", Integer.toString(i);
//returns 0 when it should return the size of the List from Reusable;
//How do I get the List From Reusable Class??
}
Как видно из размера списка в журнале, он возвращает пустой список. Как мне установить Reusable, чтобы он возвращал список при вызове других классов?
Я все еще разбираюсь в Java и Android, поэтому буду признателен за вашу помощь.
[EDIT] Может быть, это как-то связано с тем, что вызовы Firebase являются асинхронными? Потому что, как видите, пока я передаю результаты параметрам, журналы возвращают полный список. Но вызов метода вне этой цепочки, возможно, запускает его выполнение вне потока Firebase, где список все еще пуст.
Для чего нужен processListOfUsers? Это для удаления повторяющихся пользователей ...? Похоже, проблема здесь. Во-первых, вы удаляете / очищаете элементы из list (= mUserList) в то время как, проходя через него. И, во-вторых, вы передаете mUserList, когда в этом нет необходимости, потому что он уже является членом класса (вы можете получить к нему доступ непосредственно внутри processListOfUsers).
Нет, Джино. Журнал (StepThree) также возвращает размер списка. И я не могу получить доступ из processListOfUsers, потому что для этого требуется параметр списка. Он получает список пользователей с дубликатами и удаляет его. Если я передам пустой список из другого класса, он также вернется пустым.
Не имеет отношения к непосредственной проблеме, но если вы ожидаете, что один и тот же список будет доступен для разных действий, вам нужно будет создать синглтон или несколько статических переменных.
Ты прав, Тайлер. Спасибо вам всем.
Ох, хорошо. Извините, меня смущают скобки, я думал, что метод принадлежит к тому же классу. Да, вам придется сделать mUserList доступным для этого метода вместо того, чтобы передавать его.
Можете ли вы исправить фигурные скобки, чтобы было понятно, какие методы входят в цикл, а какие нет? Как заметил Джино, processListOfUsers в том виде, в котором он был написан, похоже, повторяет mUserList, добавляет свои записи к себе и очищает себя внутри цикла for-each. Было бы полезно превратить это в рабочий пример, демонстрирующий проблему.
вы только что создали экземпляр idList, а затем добавляете к нему идентификатор внутри метода getUsersIdFromDb (). Где идентификаторы?
@TylerV готово. AIK, идентификаторы - это идентификаторы, полученные из базы данных. Отредактировал вопрос, чтобы прояснить это.
Опубликованный вами код все еще содержит синтаксические ошибки. Если я их исправлю, список все равно будет очищен внутри самого цикла, что является недопустимым (и приводит к исключению ConcurrentModificationException). Например, удалите контекст, поместите в список фиктивные элементы, имитирующие поиск в базе данных, и создайте пример, который может запустить кто-то другой, который воспроизводит проблему. Если я удалю сомнительный код в processListOfUsers, он будет работать должным образом и не отобразит описанную вами проблему.
Это мое лучшее предположение о том, что вы пытаетесь сделать, и оно работает. pastebin.com/UHRYLsKy




Я не совсем понял, в чем проблема, которую вы пытаетесь решить. Если это факт, что он возвращает ноль, то это потому, что вы никогда не заполняете список ничем в этом коде. Список есть, он просто пуст.
Конструктор создает пустой список (размер 0)
public Reusable (Context context){
mContext = context;
mUserList= new ArrayList<>();
}
Тогда вы действительно получите список.
Сначала вы создаете новый объект многократного использования, который создает внутри него пустой список
Reusable reusable = new Reusable(SomeClass.this);
Тогда вы получите размер этого списка, равный нулю int i = reusable.getList().size();
Здесь ошибки нет, просто нужно заполнить список в конструкторе или где-то еще.
Список заполняется внутри Reusable с помощью метода getUsersIdFromDb (), который вызывает другие методы изнутри. Но он не обновляет mlist. Я отредактировал свой вопрос, включив в него вызов getUsersIdFromDb (), который я забыл. Результат тот же: нет списка.
Привет, Джино. Да, проверял. Все правильно регистрируется внутри класса многоразового использования. Проблема заключается в его создании.