Мое приложение Android зависает, хотя нет задач с потоками пользовательского интерфейса, память и использование процессора в порядке - PullRequest
0 голосов
/ 16 февраля 2019

Я занимаюсь разработкой приложения для Android.Каждое действие связывается с сервисом, который используется для выполнения всей фактической работы.Обычно все работает отлично, но не тогда, когда массив с около 100 000 объектов поступает с сервера в качестве обновления.

После того, как вставлено около 10 000 объектов, поток БД и даже поток пользовательского интерфейса зависают.Загрузка процессора никогда не превышает 60%, используемая память - менее 200 МБ.

Я выполняю всю свою работу с БД в отдельном потоке службы;Я стараюсь не перегружать очередь Db, просто извлекая объекты из JsonArray, чтобы в очереди потоков БД всегда было около 100 объектов.

Когда большой массив с обновлениями поступает с сервера в виде массива JsonЯ постепенно разбираю его и работаю с каждым объектом в отдельности.

Очередь БД использует Room для доступа к базе данных.

`@Update(onConflict = OnConflictStrategy.FAIL)`
`public abstract void update(User localTransport);`

Транзакций нет.

Идентификаторы всех объектов БД хранятся в HashMap, поэтому я могу выбрать обновление или вставку строки без издержек.

Вот моя функция обновления:

private long doUpdateOrInsert(Sendable s) {
    if (Core.core.dbHelper.storage.hasItem(s)) {
        dbDao.updateSendable(s);
        return s.id;
    }
    else {
        long id = this.dbDao.insert(s);
        Core.core.dbHelper.storage.addItem(s,id);
        return id;
    }
}

Пожалуйста, не могли бы вы сказать мне, как решить эту проблему?Почему мой поток пользовательского интерфейса зависает?Я не вижу ничего необычного в журналах, кроме ANR, потому что пользовательский интерфейс не отвечает в течение пяти секунд, и мои журналы о том, что мой поток БД прекращает обрабатывать сообщения.Вся моя работа выполняется на Сервисе.Он отделен от действий, запущенных с startService(), и привязан к текущей деятельности.Db Thread запускается отдельным потоком в Сервисе.

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

Темы

Память

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Используйте IntentService, чтобы работа выполнялась в фоновом потоке.

Я попытался создать поток, который будет выполнять загрузку / выгрузку, но как только Служба будет завершена, Android уничтожит мой поток.

Именно поэтому вы должны использовать IntentService, поскольку Android управляет как фоновым потоком, так и остановкой Службы за вас.Вы просто отправляете работу через

startService()

и выполняете работу в onHandleIntent().

Класс обслуживания использует основной поток приложения, в то время как IntentService создает рабочий поток и использует этот поток для запускасервис.

0 голосов
/ 16 февраля 2019

Возможно, попробуйте использовать rxJava для операций с БД (используйте планировщики для потоков) и используйте события для обновления пользовательского интерфейса

...