2

The GCM Sample Project дает затушил пример отправки маркера GCM на сервер:Android GCM Отправка маркера на сервер

public class RegistrationIntentService extends IntentService { 

    ... 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     try { 
      ... 
      String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), 
        GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 

      Log.i(TAG, "GCM Registration Token: " + token); 

      // TODO: Implement this method to send any registration to your app's servers. 
      sendRegistrationToServer(token); 
      ... 
     } catch (Exception e) { 
      ... 
     } 
    } 

    /** 
    * Persist registration to third-party servers. 
    * 
    * Modify this method to associate the user's GCM registration token with any server-side account 
    * maintained by your application. 
    * 
    * @param token The new token. 
    */ 
    private void sendRegistrationToServer(String token) { 
     // Add custom implementation, as needed. 
    } 
} 

, но это делается в IntentService, которая заканчивается, как только onHandleIntent возвращается правильно? Так что, если начиная HTTP-вызова, чтобы послать маркер с популярной android-async-http библиотеке, я даже не видя мой onStart удар:

private void sendRegistrationToServer(String token) { 
    post("/devices", params, new AsyncHttpResponseHandler() { 
     // TODO: MAKE SURE ONSTART ACTUALLY CALLED TO MAKE SURE REQUEST AT LEAST GOES UPSTREAM EVEN IF I DON'T RECEIVE A CALLBACK SINCE IN INTENTSERVICE 
     // IF NOT THEN MIGHT HAVE TO CHANGE THE INTENTSERVICE TO A SERVICE FOR DEVICE REGISTRATION 
     @Override 
     public void onStart() { 
      // not actually using callback because request sent from intentservice 
      Log.d("tagzzz", "sending upstream"); 
     } 

     @Override 
     public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 
      // not actually using callback because request sent from intentservice 
     } 

     @Override 
     public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { 
      // not actually using callback because request sent from intentservice 
     } 
    }); 
} 

Будет ли мой запрос HTTP даже послал вверх по течению, прежде чем onHandleIntent возвращается и заканчивает IntentService? Если нет, то почему Google дает это в качестве своего примера для отправки вашего токена на ваш сервер?

+2

IntentService имеет выделенный фоновый поток, на котором он работает. Поэтому вам не нужно запускать HTTP-вызов в другом потоке, вместо этого использовать текущий фоновый поток. Если вы действительно хотите использовать выделенный поток для вызова веб-сервиса, вы можете предотвратить выполнение Intent Service onHandleIntent с помощью CountdownLatch. Но это нехороший подход. Пожалуйста, поделитесь своими материалами? –

+0

@SagarTrehan извините, я не понимаю, что вы имеете в виду, когда говорите «вам не нужно начинать HTTP-вызов в другом потоке, а не в текущем фоновом потоке пользователя». Я запускаю HTTP-вызов в текущем потоке, но проблема с асинхронным обратным вызовом, которая передается вызову библиотеки http. –

ответ

3

Будет ли отправлен мой запрос HTTP еще до того, как onHandleIntent вернет и завершит IntentService?

Учитывая, что вы используете библиотеку с именем «android-async-http», я бы предположил, что поведение по умолчанию заключается в том, что он выполняет асинхронное выполнение HTTP. Неопределенно, будет ли вызов post() завершить свою работу до того, как onHandleIntent() вернется, но это кажется маловероятным.

Почему Google дает это в качестве примера для отправки вашего токена на ваш сервер?

Google этого не делает. У Google есть заглушка sendRegistrationToServer(), как вы можете видеть в своем первом списке кодов. Я не знаю ни одного примера Google, использующего библиотеку «android-async-http».

Вы,, решили использовать асинхронный механизм для отправки этого HTTP-запроса. Это неправильный выбор для внутри IntentService. Теперь, возможно, эта библиотека имеет синхронный вариант, и в этом случае вы можете переключиться на это. В противном случае используйте что-то еще синхронное для HTTP-запроса (HttpURLConnection, OkHttp3 и т. Д.) Из IntentService.

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

+0

Ах, ну, если я использую синхронный HTTP-вызов, «IntentService» останется в живых, пока я не получу ответ с сервера? –

+1

@AdamJohns: Да. Предполагая, что ваша операция HTTP должна быть довольно короткой (например, второй или второй), это все, что вам нужно. Для большой работы вам может потребоваться начать думать о 'WakeLock' и т. Д. – CommonsWare

+0

Отлично, спасибо за разъяснение! –

Смежные вопросы