/* * Copyright (c) 2010-2016, openHAB.org and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.habdroid.util; import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; /** * This class is similar to the {@link android.app.IntentService}, * with the main difference that this service does not stop itself automatically * once the intent has been handled. * * This behaviour is necessary for example if the subclass has to wait for asynchronous callbacks. * */ public abstract class ContinuingIntentService extends Service { private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; private final String mName; private int mLastStartId = 0; private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); } } /** * Creates a {@link ContinuingIntentService}. * * @param name Used to name the worker thread, important only for debugging. */ public ContinuingIntentService(String name) { super(); mName = name; } @Override public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public int onStartCommand(Intent intent, int flags, int startId) { mLastStartId = startId; Message msg = mServiceHandler.obtainMessage(); msg.obj = intent; mServiceHandler.sendMessage(msg); return START_NOT_STICKY; } /** * @return The start ID of the latest intent received. */ protected int getLastStartId(){ return mLastStartId; } @Override public void onDestroy() { mServiceLooper.quit(); } @Override public IBinder onBind(Intent intent) { return null; // binding not supported } /** * 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. * When all requests have been handled, the IntentService does not stop itself, * so you need to call {@link #stopSelf} manually. * * @param intent The value passed to {@link * android.content.Context#startService(android.content.Intent)}. */ protected abstract void onHandleIntent(Intent intent); }