2010-12-16 9 views
5

単純な数値の優先度に基づいてインテントを処理するIntentServicesource code)を実装したいと思います。優先順位の高いインテントは、優先順位の低いインテントよりも最初にサービスによって処理される必要があります。Androidの優先キューを使用したサービス

Androidにはこれが既にありますか?そうでない場合は、それを実装する方法の指針はありますか?

答えて

18

CommonsWareの回答とAndroidのIntentServicesource codeに基づいて、優先度の高いインテントサービスを実装するための最初の試みです。広範囲にテストし、それに応じて編集します。

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

しかし、IntentServiceにはそれほど多くはありません。 Handler + Looperではなく、PriorityBlockingQueueに裏打ちされたPriorityIntentServiceを調理することは、はるかに長いはずがありません。

+0

ありがとうCommonsWare。正しい方向に私を向ける疑似コードを少し追加してもよろしいですか?私はPriorityBlockingQueueがインテントを格納しているはずであり、コンパレータは異なる優先順位を区別する必要があると思います。しかし、同じ優先順位のインテントをどのように注文するかはわかりません。 – hpique

+0

@hgpc:他の基準がない場合は、ハッシュコードなどを比較してください。 – CommonsWare

+0

@CommonsWareインテントには何らかのタイムスタンプがありますか? – hpique

関連する問題