#android #parse-platform
#Android #parse-платформа
Вопрос:
Ситуация
- Я пишу приложение для обмена сообщениями для Android, используя Parse.com в качестве серверной части
- Есть действие, показывающее список сообщений, отправленных текущему зарегистрированному пользователю
- Пользователь получает push от Parse, если на сервере для него есть новое сообщение
Я пытаюсь выполнить это в два этапа:
- Когда начинается это действие (в его
onCreate
методе), я извлекаю все сообщения для текущего пользователя из серверной части Parse и сохраняю их в локальном хранилище данных, если в хранилище данных уже были какие-либо сообщения, все они удаляются (открепляются), а вместо этого закрепляются извлеченные сообщения - Затем я запрашиваю сообщения в локальном хранилище данных и с результатами обновляю список сообщений (заполняя
ArrayList<Message>
переменную и вызываяnotifyDataSetChanged
адаптер, используя эту переменную в качестве источника данных)
Почему в два этапа?
Я разделил его на два этапа, потому что, когда выполняется действие и пользователь получает от серверной части Parse сообщение о том, что для него есть / есть новые сообщения, я извлекаю только новые сообщения аналогичным образом (но не совсем так) на шаге 1., а затем вызываюточно такая же функция обновления, как на шаге 2. Для этого используется широковещательный приемник, обрабатывающий запросы
Шаг 1.
Следующий фрагмент кода показывает, как я извлекаю все сообщения с сервера на шаге 1 в onCreate
методе действия
ParseQuery<Message> query = ParseQuery.getQuery(Message.class);
query.whereEqualTo("recipient", ParseUser.getCurrentUser());
query.addDescendingOrder("createdAt");
query.findInBackground(new FindCallback<Message>() {
@Override
public void done(final List<Message> messages, ParseException e) {
if (e == null amp;amp; messages.size() > 0) {
ParseObject.unpinAllInBackground("messages",
new DeleteCallback() {
@Override
public void done(ParseException e) {
ParseObject.pinAllInBackground("messages",
messages, new SaveCallback() {
@Override
public void done(
ParseException e) {
for (Message message : messages) {
if (message.getStatus() == 0) {
message.setStatus(1);
message.saveEventually();
}
}
refreshList();
}
});
}
});
}
}
});
Часть, когда статус изменяется с 0 на 1, заключается в том, чтобы изменить сообщение с нового на непрочитанное
Для полноты картины и для документирования слов, написанных в Почему в два этапа?, вот как я получаю только новые сообщения в onReceive
широковещательном приемнике, обрабатывающем запросы из серверной части Parse
Broadcast receiver snippet
public void onReceive(Context context, Intent intent) {
ParseQuery<Message> query = ParseQuery.getQuery(Message.class);
query.whereEqualTo("recipient", ParseUser.getCurrentUser());
query.whereEqualTo("status", 0);
query.addDescendingOrder("createdAt");
query.findInBackground(new FindCallback<Message>() {
@Override
public void done(final List<Message> messages, ParseException e) {
if (e == null amp;amp; messages.size() > 0) {
ParseObject.pinAllInBackground("messages", messages,
new SaveCallback() {
@Override
public void done(ParseException e) {
for (Message message : messages) {
message.setStatus(1);
message.saveEventually();
}
refreshList();
}
});
}
}
});
}
Шаг 2. Функция refreshList
private void refreshList() {
ParseQuery<Message> query = ParseQuery.getQuery(Message.class);
query.fromPin("messages");
query.whereEqualTo("recipient", ParseUser.getCurrentUser());
query.addDescendingOrder("createdAt");
query.findInBackground(new FindCallback<Message>() {
@Override
public void done(final List<Message> messages, ParseException e) {
items.clear();
for (Message m : messages) {
items.add(m);
}
adapter.notifyDataSetChanged();
}
});
}
Другие переменные
ArrayList<Message> items;
MessageArrayAdapter adapter;
Где MessageArrayAdapter
просто расширяет ArrayAdapter
Зачем мне вообще нужно использовать локальное хранилище данных?
- Активность может существовать довольно долго
- … и пользователь может получать новые сообщения при выполнении действия
- Я не хочу запрашивать сервер каждый раз, когда появляется новое сообщение для всех сообщений
- Я знаю, что мог бы запросить только новые и добавить их в
items
when это переменная-член действия, в котором все это происходит. В таком случае мне вообще не нужно было использовать локальное хранилище данных - Причина ее использования заключается в том, что в будущем я планирую полностью перенести выборку всех сообщений из activity — например, для запуска всего приложения или, возможно, для обслуживания периодической выборки сообщений
Является ли это приемлемым способом решения этой проблемы?
Комментарии:
1. Вы используете локальное хранилище данных для сохранения сообщений в случае, если пользователь переходит от вашего приложения, выходит из системы, теряет подключение к Интернету и т.д. Если бы вы полагались только на свои облачные записи, приложение не смогло бы прочитать ни одного сообщения. По крайней мере, с помощью локального хранилища данных вы можете кэшировать данные локально