2010-12-16 5 views

답변

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