Android 中具有优先级队列的服务

发布于 2024-10-07 14:47:56 字数 381 浏览 0 评论 0原文

我想实现一个 IntentService (源代码) 基于简单的数字优先级处理意图。服务应首先处理优先级较高的意图,而不是优先级较低的意图。

Android 上有什么东西可以做到这一点吗?如果没有,有关于如何实施的指导吗?

I'd like to implement an IntentService (source code) that handles intents based on a simple numeric priority. Intents with higher priority should be processed first by the service than intents with lower priority.

Is there anything on Android that does this already? If not, any pointers on how to implement it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

霓裳挽歌倾城醉 2024-10-14 14:47:56

首次尝试基于 CommonsWare 的回答和 Android 的 IntentService 源代码。将进行广泛测试并进行相应编辑。

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;
    }
}

A first attempt at an implementation of a intent service with priorities, based on CommonsWare's answer and Android's IntentService source code. Will test extensively and edit accordingly.

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;
    }
}
她比我温柔 2024-10-14 14:47:56

并不真地。不过,IntentService 并没有太多内容。烹制一个由 PriorityBlockingQueue 支持的 PriorityIntentService,而不是 Handler+Looper,应该不会太长。

Not really. There isn't much to IntentService, though. Cooking up a PriorityIntentService backed by a PriorityBlockingQueue, rather than a Handler+Looper, shouldn't be much longer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文