Фон
У нас есть большое приложение, которое имеет различные функции, использует несколько библиотек и обрабатывает телефонные звонки, используя BroadcastReceiver
:
<receiver android:name="....PhoneBroadcastReceiver">
<intent-filter >
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
<intent-filter >
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
Проблема
Недавно я заметил, что если мы закроем приложение, используя недавние задачи, BroadcastReceiver
получает намерения довольно много времени (3-5 секунд) после того, как телефон начинает звонить.
Это проблема, потому что приложение должно обрабатывать телефонные звонки прямо сейчас.
Что я пробовал и нашел
В POC, похоже, работает просто отлично. Даже в одном из моих репозиториев ( здесь ), который предназначен для записи телефонных звонков, если я добавлю журналы в BroadcastReceiver
вместо реальной логики, я вижу, что обрабатываются сразу. Я даже добавил все разрешения большого приложения в этот пример приложения, которое я создал (и предоставил), и оно все еще работало на отлично. Добавление библиотек, которые использует большое приложение, может занять много времени для добавления и тестирования, к сожалению
Я думал, что, может быть, класс, который выходит из Application (или, если быть точным, MultiDexApplication
), занимал слишком много времени, поэтому я добавил туда журнал (начало onCreate
). Это действительно занимает немного времени (секунды или около того), но журнал показывается через некоторое время, и разница между ним и журналом BroadcastReceiver
очень мала. Таким образом, проблема должна быть вызвана чем-то более глубоким, чем Приложение или BroadcastReceiver
.
Я подумал, что, может быть, это потому, что мы используем мультидексинг. Я пытался отключить его, но это не помогло. Я не думаю, что это может даже повлиять на это, поскольку я попробовал это на Android P на Pixel 2.
Я пытался установить приоритет BroadcastReceiver
. Пытался установить его на 999 (то есть максимально допустимый ) и даже на 2147483647, но ни один из них не помог.
Я подумал, что, возможно, ОС выделяет много памяти для приложения, что может занять некоторое время, но я знаю, что другие приложения, которые слушают те же Intents (например, TrueCaller), работают нормально даже после того, как я закройте приложение из последних задач. Я также проверил, сколько памяти использует приложение и сколько TrueCaller использует. Приложение использует в среднем 33 МБ ОЗУ на моем Pixel 2, а TrueCaller - 2 МБ. Я получил эти значения с экрана параметров разработчика «Использование памяти». Странно то, что он говорит о том, что максимальное использование ОЗУ огромно (около 1 ГБ) даже при запуске приложения с нуля, но я никогда не видел его в профилировщике, даже близко (около 200 МБ). Я думаю, что этот экран не надежный способ проверить использование памяти.
Я думал, что, возможно, исключение приложения из оптимизации батареи может помочь, но это не помогло. Даже TrueCaller, который запрашивает это у пользователей, не нуждается в этом в этом сценарии. Там работает нормально, не устанавливая его.
Единственное, что я думаю, может быть причиной этого, это библиотеки, которые использует приложение. И их много, но мне интересно, что может повлиять на приложение еще до того, как будет вызван класс, расширяющий Application ... К сожалению, их так много, что потребуется много времени, чтобы добавить их в проект POC. Я думаю, что сделаю это, но мне интересно, может ли это быть причиной.
Вопросы
Что может повлиять на BroadcastReceiver
, чтобы получить свое намерение так поздно? Возможно, это одна из вещей, о которых я упомянул?
Почему экран «использования памяти» выглядит настолько ненадежным и противоречащим тому, что я вижу на профилировщике IDE? Может ли это быть причиной позднего намерения (огромного выделения памяти ОС)?
EDIT: я заметил, что инициализация некоторых библиотек заняла слишком много времени при вызове onCreate класса, расширяющего Application, поэтому я поместил некоторые из них в фоновые потоки, а некоторые даже удалили.
Кажется, это лучше, но, тем не менее, проблема в том, что приложение запускается слишком поздно после звонка телефона, и поэтому проблема все еще существует.