2010-12-16 11 views
5

Me gustaría implementar un IntentService (source code) que maneja los intentos basados ​​en una prioridad numérica simple. Los intentos de prioridad más alta deben ser procesados ​​primero por el servicio que los intentos con mayor prioridad.Servicio con cola de prioridad en Android

¿Hay algo en Android que ya lo haga? Si no, ¿algún indicador sobre cómo implementarlo?

Respuesta

18

Un primer intento de implementación de un servicio intencionado con prioridades, basado en la respuesta de CommonsWare y IntentService de Android source code. Probará extensivamente y editará en consecuencia.

public abstract class PriorityIntentService extends Service { 

    private final class QueueItem implements Comparable<QueueItem> { 
     Intent intent; 
     int priority; 
     int startId; 

     @Override 
     public int compareTo(QueueItem another) { 
      if (this.priority < another.priority) { 
       return -1; 
      } else if (this.priority > another.priority) { 
       return 1; 
      } else { 
       return (this.startId < another.startId) ? -1 : 1; 
      } 
     } 
    } 
    private final class ServiceHandler extends Handler { 
     public ServiceHandler(Looper looper) { 
      super(looper); 
     } 

     @Override 
     public void handleMessage(Message msg) { 
      try { 
       final QueueItem item = mQueue.take(); 
       onHandleIntent(item.intent); 
       if (mQueue.isEmpty()) { 
        PriorityIntentService.this.stopSelf(); 
       } 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
    public static final String EXTRA_PRIORITY = "priority"; 
    private String mName; 
    private PriorityBlockingQueue<QueueItem> mQueue; 
    private boolean mRedelivery; 
    private volatile ServiceHandler mServiceHandler; 
    private volatile Looper mServiceLooper; 

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

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

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

     mServiceLooper = thread.getLooper(); 
     mServiceHandler = new ServiceHandler(mServiceLooper); 
     mQueue = new PriorityBlockingQueue<QueueItem>(); 
    } 

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

    protected abstract void onHandleIntent(Intent intent); 

    @Override 
    public void onStart(Intent intent, int startId) { 
     final QueueItem item = new QueueItem(); 
     item.intent = intent; 
     item.startId = startId; 
     final int priority = intent.getIntExtra(EXTRA_PRIORITY, 0); 
     item.priority = priority; 
     mQueue.add(item); 
     mServiceHandler.sendEmptyMessage(0); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     onStart(intent, startId); 
     return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; 
    } 

    public void setIntentRedelivery(boolean enabled) { 
     mRedelivery = enabled; 
    } 
} 
2

No realmente. Sin embargo, no hay mucho para IntentService. Cocinar un PriorityIntentService respaldado por un PriorityBlockingQueue, en lugar de un Handler + Looper, no debería ser mucho más largo.

+0

Gracias CommonsWare. ¿Te importaría agregar un poquito de pseudo-código para apuntarme en la dirección correcta? Supongo que PriorityBlockingQueue debe almacenar los intentos, y el comparador debe diferenciar entre las diferentes prioridades. Sin embargo, no estoy seguro de cómo ordenar los intentos de la misma prioridad. – hpique

+0

@hgpc: si no tiene ningún otro criterio, compare los códigos hash o algo. – CommonsWare

+0

@CommonsWare ¿Tiene alguna intención algún tipo de marca de tiempo? – hpique

Cuestiones relacionadas