Почему я получаю бесконечный цикл при вызове двух служб Intent один за другим?

Я перейду прямо к делу.

Мне нужно использовать некоторые веб-службы Google (DistanceMatrix and Geocoding APIs), прежде чем я смогу продолжить следующий шаг, необходимо получить оба ответа. Я только что встретил IntentServices и прочитал, что это, возможно, хороший способ выполнить одну задачу, а затем другую, потому что они могут общаться, используя Intents и BroadcastReceivers. Таким образом, второй IntentService будет знать, когда первый выполнил свою работу.

Следующие шаги суммируют то, чего я хочу достичь.

  1. Получить ответ от DistanceMatrix API
  2. Как только эта задача будет выполнена, запустим другую службу Intent и передадим ответ, чтобы я мог получить адрес из второй службы Intent и геокодировать ее с помощью Geocoding API.

Однако, прежде чем я сделал эту реализацию, я тестировал код, отправляющий некоторые сообщения на консоль, чтобы убедиться, что обе службы намерений могут общаться друг с другом, но я получаю бесконечный цикл.

I/MapFragment: DistanceMatrixService finished...
I/MapFragment: Running GeocodingService...
I/MapFragment: GeocodingService finished...
I/MapFragment: The whole process has finished...
I/MapFragment: DistanceMatrixService finished...
I/MapFragment: Running GeocodingService...
I/MapFragment: GeocodingService finished...
I/MapFragment: The whole process has finished...
I/MapFragment: DistanceMatrixService finished...
I/MapFragment: Running GeocodingService...
I/MapFragment: GeocodingService finished...
I/MapFragment: The whole process has finished...
I/MapFragment: DistanceMatrixService finished...
I/MapFragment: Running GeocodingService...
I/MapFragment: GeocodingService finished...
I/MapFragment: The whole process has finished...

Первый IntentService вызывается при нажатии кнопки

@Override
public void onClick(View v) {
    Intent msgIntent = new Intent(getActivity(), DistanceMatrixService.class);          
    getActivity().startService(msgIntent);
}

Класс DistanceMatrixService просто отправляет сообщение обратно в основной фрагмент.

public class DistanceMatrixService extends IntentService {

    public static final String ACTION_FINISHED = "ACTION_FINISHED";

    public DistanceMatrixService() {
        super("DistanceMatrixService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        // Run the heavy task just here
        //...

        // Once the job is done send a broadcast message to communicate that it has finished
        Intent bcIntent = new Intent();
        bcIntent.setAction(ACTION_FINISHED);
        sendBroadcast(bcIntent);
    }
}

Когда первый IntentService завершает работу, запускается GeocodingServices.

private class DistanceMatrixBroadcastReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
            if(intent.getAction().equals(DistanceMatrixService.ACTION_FINISHED)){
                Log.i(LOG_TAG, "DistanceMatrixService finished...");
                Log.i(LOG_TAG, "Running GeocodingService...");                    

                Intent msgIntent = new Intent(getActivity(), GeocodingService.class);
                getActivity().startService(msgIntent);
            }
    }

}

Как и первый IntentService, этот просто отправляет сообщение основному фрагменту.

 public class GeocodingService extends IntentService{

    public static final String ACTION_FINISHED = "ACTION_FINISHED";

    public GeocodingService() {
        super("GeocodingService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        // Run the heavy task just here
        //...

        // Once the job is done send a broadcast message to communicate that it has finished
        Intent bcIntent = new Intent();
        bcIntent.setAction(ACTION_FINISHED);
        sendBroadcast(bcIntent);
    }

}

И класс GeocodingBroadcastReceiver ловит сообщение

private class GeocodingBroadcastReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals(GeocodingService.ACTION_FINISHED)){
            Log.i(LOG_TAG, "GeocodingService finished...");
            Log.i(LOG_TAG, "Running The process has finished...");
        }
    }

}

И, наконец, это код для регистрации обоих BroadcastReceivers, которые вызываются в методе onCreate().

    private void registerGeocodingReceiver(){
    IntentFilter filter = new IntentFilter();
    filter.addAction(GeocodingService.ACTION_FINISHED);
    GeocodingBroadcastReceiver receiver = new GeocodingBroadcastReceiver();
    getActivity().registerReceiver(receiver, filter);
}

private void startDistanceMatrixReceiver(){
    Intent msgIntent = new Intent(getActivity(), DistanceMatrixService.class);
    msgIntent.putExtra("iteraciones", 10);
    getActivity().startService(msgIntent);
} 

person Sandoval0992    schedule 28.05.2017    source источник
comment
Вы используете одно и то же действие для обеих трансляций и обоих приемников — "ACTION_FINISHED".   -  person Mike M.    schedule 28.05.2017
comment
Я думаю, вам нужно сделать ваши строки ACTION_FINISHED уникальными. По сути, вы регистрируете оба BroadcastReceiver с одним и тем же фильтром.   -  person Dave    schedule 28.05.2017
comment
Да, это была проблема, я просто изменил значение ACTION_FINISHED для обоих классов. Спасибо вам всем.   -  person Sandoval0992    schedule 28.05.2017


Ответы (1)


Проблема заключалась в том, что оба сервиса имеют объявление константы с одинаковым значением.

GeocodingService.ACTION_FINISHED = "ACTION_FINISHED";
DistanceMatrixService.ACTION_FINISHED = "ACTION_FINISHED";

Просто присвойте каждому свое значение.

GeocodingService.ACTION_FINISHED = "GEOCODING_FINISHED";
DistanceMatrixService.ACTION_FINISHED = "DISTANCE_MATRIX_FINISHED";

Еще раз спасибо пользователям, давшим правильный ответ!

person Sandoval0992    schedule 28.05.2017