2012-06-28 5 views
13

Я имею в виду android design considerations: AsyncTask vs Service (IntentService?)IntentService будет убит после того, как я перестану мое заявление

Согласно дискуссии, AsyncTask не устраивает, потому что это сильно «привязан» к вашей деятельности

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

  • Я бросить мое заявление, сохраняя нажав на спине клавишу, пока не увидел домашний экран. Поток все еще работает.
  • Я убить мое заявление, перейдя Управление приложениями -> App -> Force остановить. Поток остановлен.

Итак, я ожидаю, после того, как я меняю от Thread к Service, мой Service будет держать в живых даже после того, как я бросить или убить мое приложение.


Intent intent = new Intent(this, SyncWithCloudService.class); 
startService(intent); 

public class SyncWithCloudService extends IntentService { 
    public SyncWithCloudService() { 
     super("SyncWithCloudService"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     int i = 0; 
     while (true) { 
      Log.i("CHEOK", "Service i is " + (i++)); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException ex) { 
       Log.i("CHEOK", "", ex); 
      } 
     } 
    } 
} 

// Doesn't matter whether I use "android:process" or not. 
    <service 
     android:name="com.xxx.xml.SyncWithCloudService" 
     android:process=".my_process" > 
    </service> 

Однако, мой вывод заключается в том, что

  • I quit мое приложение, сохраняя нажатие на программную клавишу «Назад», пока я не увидел домашний экран. Служба все еще работает.
  • Я убить мое заявление, перейдя Управление приложениями -> App -> Force остановить. Служба остановлена.

Похоже, что поведение Service и Thread одинаково. Итак, почему я должен использовать Service вместо Thread? Я что-то пропустил? Я думал, что мой Service должен продолжать работать, даже после того, как я убью свое приложение?

ответ

10

Неа. Служба перестанет работать, когда вы убьете свое приложение. Когда вы убиваете приложение, все его компоненты убиты (действия, службы и т. Д.).

В общем поведении Thread и услуг похожи.Тем не менее, если вы запустите Thread из Activity и затем завершите работу (то есть: закройте приложение), в конечном итоге Android заметит, что ваш процесс не имеет в нем активных компонентов (поскольку Android не распознает ваш Thread как активный компонент) и он просто убьет ваш процесс, тем самым убив поток.

Однако, если у вас есть служба, то Android заметит, что у вас есть работа, работающая, а не так легко убить ее. Тем не менее, по-прежнему возможно, что Android убьет ваш сервис, если он не «используется».

+2

Но мое тестирование является то, что, когда я оставил свою заявку (нажимать назад программную клавишу несколько раз, пока я не дойду до главного экрана), поток все еще работает. Это потому, что мне просто повезло, что ОС не убивает мой поток? –

+2

Да, ваш поток будет работать некоторое время, пока Android не решит убить процесс. Он не делает это сразу, он делает это только тогда, когда и когда ему это нравится. У вас нет контроля над тем, когда процесс будет убит. –

+0

OK. Благодарю. Я попробую запустить его в течение нескольких часов и посмотреть, как это работает. Для обслуживания, Android «гарантия» не убивает его? Поскольку у меня в нем бесконечная петля (для тестирования). –

1

Вы используете startService(). Service будет работать до тех пор, пока код не будет выполнен, или пока Android не решит, что он должен быть убит. Посмотрите на bound services. На вашем Activity.onDestroy() вы должны позвонить unbindService().

4

На самом деле существуют различные виды услуг, которые вы можете реализовать. Используйте Service вместо IntentService. Там вам нужно посмотреть START_STICKY, START_NOT_STICKY и START_REDELIVER_INTENT, чтобы вы могли работать в фоновом режиме, даже если ваша деятельность умирает. Android services

1

В вашем IntentService вы можете переопределить onStartCommand() возвращение START_REDELIVER_INTENT

Тогда, если убит, ваша служба будет перезапущен автоматически системой через некоторое время с тем же Намерения.

Обязательно вызовите супер реализацию на onStartCommand(), как это:

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    super.onStartCommand(intent,flags,startId); 
    return START_REDELIVER_INTENT; 
} 
Смежные вопросы