Общая ситуация. В мобильном приложении собираются некоторые данные и периодически отправляются на сервер. Данные порождаются в виде объектов, которые записываются в базу. Процедура из минутного таймера запросом выбирает данные, восстанавливает изначальные объекты и, если данные существуют, то они отправляется на сервер. Данные могут порождаться как при интерактивной работе пользователя в Activity, так и в фоне в рамках работающего Service, который обрабатывает некоторые данные автоматически.
Технические подробности. Одно из полей объекта, который описывает событие, имеет тип java.util.Date - дата возникновения события. В базе оно хранится в виде поля типа INTEGER (хотя как мы знаем в SQLite это условность). При записи в базу я использую метод getTime() из даты. При восстановлении из базы я использую конструктор с параметром этого времени (микросекунд эпохи UNIX). Далее, при отправке на сервер данных в формате JSON, я получаю getTime() и делю результат на тысячу (что бы получить нормальное время UNIX).
Проблема в следующем: Иногда сообщения уходят с правильным временем, а иногда смещенные в будущее на значение часового пояса.
У меня при тестировании такого никогда не было, а у пользователей иногда возникает. Вчера мы смогли увидеть и проследить инцидент по горячим следам. Пользователь вызвал событие в
17:57, но увидел на сайте
20:57. После этого он сообщил мне (было 18 с мелочью и потому проблема получила 100% подтверждение). У пользователя на смартфоне было правильное время и правильный часовой пояс. В логах сервера (в сырых данных) я нашел запись за
17:57:30 со следующей информацией {"Date": 1427997440 ..._другие свойства_...}, что
как не сложно убедится соответствует
02 Apr 2015 17:57:20 GMT. Таким образом установлено, что неправильное время пришло именно с мобильного приложения, а не возникло в результате сбоя обработки на сервере. К сожалению, после успешного соединения с сервером записи по переданным событиям удаляются из базы, а потому сейчас уже нельзя уточнить на котором этапе произошла проблема - до или после сохранения в БД.
Два варианта:
или в 17:57:20 конструкция (new Date()).getTime() == 1427997440000 (вместо 1427986640000)
или (new Date(1427986640000)).getTime() == 1427997440000
Какие есть идеи у уважаемых экспертов Android и опытных программистов Java?
P.S.
Возможно это будет важно. Есть мысли, что тут проблема с отложенной оптимизацией виртуальной машины. Так как в этом же проекте я сталкивался с другими необъяснимыми вещами. К примеру, есть работающий код (упрощен):
int intCount = 0;
Cursor cursor = db.rawQuery(SELECT count(*) as count FROM table, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
...............
intCount = cursor.getInt(0));
...............
}
cursor.close();
...............
object.field = intCount;
Так вот этот код часто запускается и вопросов к нему обычно нет. И вот владельцы одного из устройств стали жаловаться на падение программы. Смотрю сообщение об ошибках на Google Play - а там в последней строке этого примера (присваивание свойству объекта интовской локальной переменной) вызывается ошибка, что нельзя обращаться к данным закрытого курсора. Дописал всевдооперации с переменной до закрытия курсора и ошибка перестала возникать.