Проблема, когда приложение возвращается на передний план - PullRequest
4 голосов
/ 02 августа 2011

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

У моего приложения есть заставка, где оно загружает некоторые данные из веб-сервисов и помещает их в глобальные статические переменные, объявленные в классе, расширяющем Application, как объяснено в в этом вопросе SO . Как только все данные загружены, это действие запускает домашнее действие с некоторым меню для навигации в приложении. Глобальные переменные используются в большинстве видов деятельности.

В какой-то момент, играя с другими приложениями, кажется, что мое приложение убито, потому что я вижу это в logcat:

I/ActivityManager( 2465): Process com.mysite.myapp (pid 23538) has died.
I/WindowManager( 2465): WIN DEATH: Window{4852a678 com.mysite.myapp/com.mysite.myapp.Home paused=false}
I/WindowManager( 2465): WIN DEATH: Window{485b63a8 com.mysite.myapp/com.mysite.myapp.Home paused=false}
I/WindowManager( 2465): WIN DEATH: Window{4826fbf8 com.mysite.myapp/com.mysite.myapp.ItemList paused=false}
I/WindowManager( 2465): WIN DEATH: Window{48286f90 com.mysite.myapp/com.mysite.myapp.ItemDetail paused=false}
W/GpsLocationProvider( 2465): Unneeded remove listener for uid 1000
D/GpsLocationProvider( 2465): stopNavigating
D/gps_BRCM( 2465): [status check] on_stop() : GPS_STATUS_SESSION_END
D/gps_BRCM( 2465): gps_engine_status_update 2
D/GpsLocationProvider( 2465): send an intent to notify that the GPS has been enabled or disabled
D/gps_BRCM( 2465): gps_stop: called
V/GpsLocationProvider( 2465): hybridGpsSensorDeregister : No registered sensorManager
D/GpsLocationProvider( 2465): hybridGpsSensorDeregister

и отладчик отключен.

Теперь, когда я снова открываю свое приложение, запускается последнее действие, если оно не использует глобальные переменные (в этом случае оно вылетает, как только я перехожу к действию, которое выполняет), или немедленно вылетает, если это происходит.

Если мое приложение было убито, что, по-видимому, является причиной того, что даже моя служба определения местоположения остановлена, как видно из logcat, почему она открывает последнее действие вместо того, чтобы снова запускаться с заставки?

Ответы [ 3 ]

5 голосов
/ 02 августа 2011

Это не прямой ответ на ваш вопрос, но я подумал, что это может быть полезно.

Ваше решение хранить данные в глобальных переменных неверно. Это потому, что ваше приложение может быть убито каждый раз, когда пользователь отходит от него. И когда он или она вернется, вам нужно будет снова загрузить данные.

Вы должны использовать ContentProvider и Service. Service должен загрузить данные из интернета и сохранить их в ContentProvider. ContentProvider должны сохраняться данные. Все действия должны использовать ContentProvider для доступа к этим кэшированным данным.

Таким образом, ваше приложение:

  1. Нет необходимости загружать данные при каждом запуске приложения (экономия процессора, батареи и пропускной способности)
  2. Ваша деятельность может зависеть от того, что в ContentProvider есть кэшированные данные.
  3. Каждый раз, когда данные обновляются в ContentProvider, каждое действие может получать уведомления и обновлять пользовательский интерфейс.
  4. Данные в ContentProvider сохраняются при каждом запуске приложения (например, если вы используете SQLite).
  5. Фоновая служба, которая считывает данные из веб-службы и синхронизирует их с ContentProvider, полностью отделена от Activity.

Конечно, вам нужно потратить некоторое время на реализацию Service и ContentProvider и правильную обработку в Acitivities. Но ваше приложение будет более надежным и масштабируемым (вы можете легко добавлять новые компоненты).

2 голосов
/ 02 августа 2011

Грязное решение вашей проблемы - проверить, заполнены ли глобальные переменные в методе onResume ваших действий. Если переменные не заполнены, запустите действие заставки с намерением с установленным флагом CLEAR_TOP . Это должно привести к тому, что все ваши действия будут удалены из стека активности, и ваш начальный экран загрузится и сможет перезагрузить все данные, необходимые для работы вашего приложения.

Это грязный обходной путь, помогающий работать плохо спроектированному приложению. Если вы хотите, чтобы ваше приложение было более приятным для вас, и пользователь выбрал решение, предоставленное inazaruk. Он прав насчет базовой настройки приложения.

1 голос
/ 02 августа 2011

Когда Android убивает ваше приложение, оно делает это только для экономии ресурсов. Для лучшего удобства использования ОС запомнит, где вы находились внутри этого приложения (сохраняя такие вещи, как стек операций, в состоянии экземпляра, если вы реализуете правильные слушатели).

Когда вы восстановите ваше приложение, оно восстановит действия и все остальное. Поскольку вы сохраняли данные в глобальных статических переменных, они могли быть «потеряны» при завершении работы приложения!

Я предлагаю вам использовать базы данных или хотя бы проверить, есть ли еще данные перед их использованием (например: MyClassHolder.myGlobalStaticParameter == null)

...