Skip to content Skip to sidebar Skip to footer

Regulate Network Calls In Syncadapter Onperformsync

I m sending several retrofit calls via SyncAdapter onPerformSync and I m trying to regulate http calls by sending out via a try/catch sleep statement. However, this is blocking the

Solution 1:

The "onPerformSync" code is executed within the "SyncAdapterThread" thread, not within the Main UI thread. However this could change when making asynchronous calls with callbacks (which is our case here).

Here you are using an asynchronous call of the Retrofit "call.enqueue" method, and this has an impact on thread execution. The question we need to ask at this point:

Where callback methods are going to be executed?

To get the answer to this question, we have to determine which Looper is going to be used by the Handler that will post callbacks.

In case we are playing with handlers ourselves, we can define the looper, the handler and how to process messages/runnables between handlers. But this time it is different because we are using a third party framework (Retrofit). So we have to know which looper used by Retrofit?

Please note that if Retrofit didn't already define his looper, you could have caught an exception saying that you need a looper to process callbacks. In other words, an asynchronous call needs to be in a looper thread in order to post callbacks back to the thread from where it was executed.

According to the code source of Retrofit (Platform.java):

staticclassAndroidextendsPlatform {
    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
      if (callbackExecutor == null) {
        callbackExecutor = newMainThreadExecutor();
      }
      returnnewExecutorCallAdapterFactory(callbackExecutor);
    }

    staticclassMainThreadExecutorimplementsExecutor {
      privatefinalHandlerhandler=newHandler(Looper.getMainLooper());

      @Overridepublicvoidexecute(Runnable r) {
        handler.post(r);
      }
    }
  }

You can notice "Looper.getMainLooper()", which means that Retrofit will post messages/runnables into the main thread message queue (you can do research on this for further detailed explanation). Thus the posted message/runnable will be handled by the main thread.

So that being said, the onResponse/onFailure callbacks will be executed in the main thread. And it's going to block the UI, if you are doing too much work (Thread.sleep(SLEEP_TIME);). You can check it by yourself: just make a breakpoint in "onResponse" callback and check in which thread it is running.

So how to handle this situation? (the answer to your question about Retrofit use)

Since we are already in a background thread (SyncAdapterThread), so there is no need to make asynchronous calls in your case. Just make a Retrofit synchronous call and then process the result, or log a failure. This way, you will not block the UI.

Post a Comment for "Regulate Network Calls In Syncadapter Onperformsync"