Android: intenservice, как прервать или пропустить задачу в очереди с идентификатором

У меня есть активность ( "ApplicationActivity" ), которая вызывает службу намерения ( "DownloadService" )

НамерениеService загружает файлы из Интернета в фоновом режиме, но я хочу, чтобы иметь возможность прервать определенную загрузку.........

Итак, скажем, что я помещаю 5 файлов в очередь: файл 1,2,3,4,5

Служба намерения начинает загрузку номера 1, затем второго и так далее.... 1) Есть ли способ сказать службе намерения прервать то, что вы делаете в данный момент в событии обработки метода (в этом случае загрузка файла 1) и начать загрузку следующего?

2) Можно ли удалить элемент из очереди, поэтому, например, при загрузке файла 1, удалите файл 4 из очереди, чтобы после номера 3 он перешел прямо к 5?

Вскоре мне нужен способ общения с очередью для выполнения этих двух простых операций, но я не нашел ничего полезного в Интернете: (

Тпх

Ответы

Ответ 1

Я создаю свой собственный класс MyIntentService, копирующий оригинальную, которая довольно короткая и модифицирует методы для моей собственной цели........, в частности, для удаления элемента, который вы можете использовать методы ServiceHandler в моем случае
mServiceHandler.removeMessages(APPID);
что удалите все ожидающие сообщения сообщений с определенным кодом "что", которые находятся в очереди сообщений, это означает, что вам нужно маркировать каждое добавленное в очередь сообщение, добавляя идентификатор внутри поля "что" каждого сообщения... Например,

public void onStart(Intent intent, int startId) 
{
    super.onStart(intent, startId);
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    msg.what = intent.getIntExtra("appId", 0); \\parameters that come from the outside

Ответ 2

Спасибо @user280560, я нашел решение на основе вашего комментария:)

чтобы дать более конкретный пример, где я хотел очистить очередь в определенных случаях.

Сначала я скопировал источник IntentService.java из здесь в мой проект (нет необходимости менять имена, вы можете сохранить IntentService.java, просто импортируйте свои, а не андроиды). Затем я добавил это

public void clearQueue() {
    Debug.PrintInfo(TAG, "All requests removed from queue");
    mServiceHandler.removeMessages(0);
}

для моего источника IntentService.

Теперь, из моей службы, которая расширяет IntentService, я хотел очистить очередь, когда определенное действие (логин) было передано службе, поэтому я переопределяю onStartMethod, например:

@Override
public void onStart(Intent intent, int startId) {
    if(intent.getAction().equals(ACTION_LOGIN)) {
        //Login clears messages in the queue
        clearQueue();
    }
    super.onStart(intent, startId);
}

Работает как шарм:)

Надеюсь, что это поможет кому-то...

Ответ 3

Расширьте класс IntentService и объявите список для отмененного элемента на нем, и всякий раз, когда вы хотите отменить что-либо, добавьте его в этот список. наконец, прежде чем обращаться с вашим намерением, убедитесь, что он не был отменен!

public class MyDownloadService extends IntentService {
    private static List<String> canceledUrl;

    public static void cancelDownload(String url){
         canceledUrl.add(url);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String url = intent.getStringExtra(EXTRA_URL);

            if(!canceledUrl.contains(url)) //if download has not been canceled already
                downloadFile(url);
            else
                canceledUrl.remove(url);
        }
    }
}

Я знаю, что этот код работает, потому что я его тестировал раньше, но я не уверен, что это правильный способ сделать это!

Ответ 4

Вы можете связать себя с intentservice и создать метод для отмены или запуска загрузки.

Здесь - это быстрый учебник, который вам может понадобиться

Ответ 5

Как сказал @JeffreyBlattman выше, лучше играть безопасно, назначив свое собственное "какое" значение для сообщения, подобного этому

@Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        msg.what = 0;
        mServiceHandler.sendMessage(msg);
    }

и очистите очередь, как mServiceHandler.removeMessages(0).

Надеюсь, что это поможет.