2010-12-16 6 views
5

Ich möchte eine IntentService (source code) implementieren, die Intents basierend auf einer einfachen numerischen Priorität behandelt. Intents mit höherer Priorität sollten zuerst vom Service bearbeitet werden als Intents mit niedrigerer Priorität.Dienst mit der Prioritätswarteschlange in Android

Gibt es irgendetwas auf Android, das das schon tut? Wenn nicht, irgendwelche Hinweise, wie man es implementiert?

Antwort

18

Ein erster Versuch einer Implementierung eines Intent-Dienstes mit Prioritäten, basierend auf der Antwort von CommonsWare und Android IntentServicesource code. Wird ausgiebig testen und entsprechend bearbeiten.

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

Nicht wirklich. Es gibt nicht viel zu IntentService, obwohl. Kochen ein PriorityIntentService unterstützt durch eine PriorityBlockingQueue, anstatt eine Handler + Looper, sollte nicht viel länger sein.

+0

Dank CommonsWare. Würde es Ihnen etwas ausmachen, ein bisschen Pseudo-Code hinzuzufügen, um mich in die richtige Richtung zu lenken? Ich denke, die PriorityBlockingQueue sollte die Intents speichern, und der Komparator sollte zwischen den verschiedenen Prioritäten unterscheiden. Ich bin mir nicht sicher, wie ich die Absichten mit der gleichen Priorität bestellen soll. – hpique

+0

@hgpc: Wenn Sie keine anderen Kriterien haben, vergleichen Sie die Hash-Codes oder etwas. – CommonsWare

+0

@CommonsWare Hat eine Absicht irgendeine Art von Zeitstempel? – hpique