onStartCommand после процесса обслуживания убит, когда начал с начала липкие
Я читал документацию по Android, и мне интересно, может ли кто-нибудь пролить свет на то, что происходит с экземпляром службы, когда служба, запущенная с помощью START_STICKY, убивает процесс. Я предполагаю, что данные локального состояния (переменные экземпляра) также теряются. Делает ли Android что-нибудь, чтобы помочь повторно заполнить локальное состояние, когда он воссоздает службу?
У меня были некоторые данные, которые были отправлены в службу в намерении. В onStateCommand () я бы заполнил данные экземпляра службы основаны на том, что было в намерении. Из того, что я прочитал в документах Android, намерение, переданное onStartCommand (), будет равно null, когда служба будет убита и перезапущена (с помощью START_STICKY). Означает ли это, что я теряю как намерение, так и данные участника службы при повторном создании Службы?
4 ответов:
Когда процесс убит и воссоздан, он снова проходит весь жизненный цикл (начиная с onCreate). В зависимости от того, как он был убит и как вы сохраняете данные, он может быть доступен или недоступен для вас.
Что касается возвращения намерения, есть флаг для
START_REDELIVER_INTENTэто позволит повторно передать намерение.
Недавно я столкнулся с этой же проблемой. Служба не предоставляет встроенных средств сохранения состояния, и последнего намерения может быть недостаточно, чтобы вернуть службу в предыдущее состояние. Мое решение состояло в том, чтобы иметь состояние Activity persist и передать это состояние службе через startService(). Затем служба просто запускает события в действии, например:
- вот обновление
- что-то умерло, и вот исключение
- я был убит, пожалуйста, перезагрузите меня с любым необходимым государство
Этот подход сильно очистил мой дизайн, и как сервис, так и деятельность устойчивы к тому, чтобы быть убитыми.
Android не будет повторно заполнять "потерянные" значения данных при повторном запуске службы, поэтому ваш код должен учитывать эту возможность.
Мой подход состоит в том, чтобы использовать все непримитивные переменные состояния и оставить их как null. Таким образом, я могу проверить null и предпринять соответствующие шаги, чтобы инициализировать их как и когда.Я взял на хранение легковесные данные, которые я хочу сохранить через перезапуск приложения в настройках приложения.
Используйте внутреннюю память для сохранения объекта или его поля по отдельности.
public void writeToInternalStorage(String fileName,String userName) { try{ String endOfLine = System.getProperty("line.separator"); StringBuffer buffer = new StringBuffer(); FileOutputStream fos = openFileOutput(fileName, Context.MODE_PRIVATE); //// MODE_PRIVATE will create the file (or replace a file of the same name) and make it private to your application. Other modes available are: MODE_APPEND, MODE_WORLD_READABLE, and MODE_WORLD_WRITEABLE. buffer.append(userName.toString() + endOfLine); fos.write(buffer.toString().getBytes()); Log.v(TAG, "writeFileToInternalStorage complete.. " + buffer.toString()); // writer.write(userName); fos.close(); } catch(Exception e) { Log.v(TAG, "Error: " + e.getMessage()); ExceptionNotificationMessage("writeToInternalStorage() Error: " + e.getMessage()); } } public String readFromInternalStorage(String fileName) { try{ File file = this.getFileStreamPath(fileName); if(file.exists() == true) { Log.v(TAG, "readFileFromInternalStorage File found..."); FileInputStream fis = openFileInput(fileName); StringBuilder buffer = new StringBuilder(); int ch; while( (ch = fis.read()) != -1){ buffer.append((char)ch); } Log.v(TAG, "readFileFromInternalStorage complete.. " + buffer.toString()); fis.close(); return buffer.toString(); } } catch(Exception e) { Log.v(TAG, "Error: " + e.getMessage()); ExceptionNotificationMessage("readFromInternalStorage() Error: " + e.getMessage()); } return ""; }
Comments