Может ли IntentService работать бесконечно?

Исходя из моего понимания, IntentService будет остановлен, когда будет выполнен его текущий запрос.

Рассмотрим приведенный ниже сценарий, я буду запускать запрос IntentSerivce на каждые 100 мс, а время обработки будет составлять 90 мс для этого запроса.

Таким образом, для каждого моего запроса - вызова startSerivce услуга вызывается и через 90 мс (после завершения обработки) будет вызван onDestroy из IntentServicee.

Я хочу, чтобы этот IntentServicee работал до тех пор, пока я не остановлюсь. Возможно ли это?

Предположим, что я собираюсь сделать следующее в моей службе

  • Сконфигурируйте его
  • Отправить запрос
  • ждать ответа
  • прочитать ответ
  • Широковещательная передача в действие, которое вызывается

Шаги 1 являются общими для всех моих запросов, поэтому я думал, что смогу сделать их, когда служба запускается изначально один раз, а затем выполняет 3-6 в HandleIntent на основе запросов.

Ответы

Ответ 1

IntentService на самом деле довольно маленький класс, который обертывает обработчик, проблема заключается в том, что после обработки намерения он вызывает stopSelf().

Удаление одной строки дает вам IntentService, который должен быть явно остановлен:

public abstract class NonStopIntentService extends Service {

    private String mName;
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;

    public NonStopIntentService(String name) {
        super();
        mName = name;
    }

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            // stopSelf(msg.arg1); <-- Removed
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return START_STICKY;
    }    

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * This method is invoked on the worker thread with a request to process.
     * Only one Intent is processed at a time, but the processing happens on a
     * worker thread that runs independently from other application logic.
     * So, if this code takes a long time, it will hold up other requests to
     * the same IntentService, but it will not hold up anything else.
     *
     * @param intent The value passed to {@link
     *               android.content.Context#startService(Intent)}.
     */
    protected abstract void onHandleIntent(Intent intent);  

}

Ответ 2

IntentService расширяется от стандартного класса Service, поэтому я не понимаю, почему это не должно быть сделано таким образом. На самом деле я тоже так сделаю.;)

Ответ 3

Если вам не так много работы в службе, вы можете просто расширить регулярный сервис. Верните null в onBind() и получите команды в onStartCommand(), который возвращает START_STICKY.

Ответ 4

Вам нужно создать Service и bind для вашей службы, чтобы предотвратить ее остановку. См. docs.

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