1

I'm having a tough time figuring out why do I observe InterruptedExceptions in the SyncAdapter#onPerformSync method.

Brief intro

My project originally contained only Java code and had a working SyncAdapter pattern implemented. In the onPerfromSync method I did the following operations for each resource that I needed to sync:

  • query local sqlite database
  • send data to web server over HTTP
  • save data to local sqlite database

As the project progressed I introduced Kotlin and Coroutines and decided to use them in the SyncAdapter. Most of the resources kept the existing logic, and for a few I decided to use Coroutines. I had to bridge the onPerformSync method with a CoroutineScope so that I can launch coroutines. After doing so I started observing InterruptedExceptions occurring.

Code before (no exceptions)

class MySyncAdapter extends AbstractThreadedSyncAdapter {
   ...

   @Override
   public void onPerformSync(...) {
       syncResourceX();
       syncResourceY();
   }

   private void syncResourceX() {
      // query db
      // send to server
      // store locally
   }
}

Code After (with exceptions)

class MySyncAdapter(...): AbstractThreadedSyncAdapter(...) {
   ...

   override fun onPerformSync(...) {
      runBlocking {
              syncResourceX();
              syncResourceY();
      }
   }

   private suspend fun syncResourceX() {
      // query db
      // send to server
      // store locally
   }
}

After this refactoring I started receiving InterruptedExceptions where runBlocking is being invoked.

Initially I thought this might be due to not performing network operations on the current thread as the docs of the sync adapter state that the system monitors network traffic and might interrupt the sync process if no traffic is generated. But runBlocking should cause any network requests to be executed on the current thread right?

After which I started thinking that this process has existed in the Java code as well. It's just that there is nothing to report the interruption of the sync process. It is up until I started using coroutines and runBlocking that this problem has revealed it self. Or so I think now.

Question:

Any thoughts or explanations why I previously did not observe InterruptedException with the Java code and do observe InterruptedException with the Kotlin code is more than welcome.

Notes

  • I haven't overriden onSyncCanceled
  • The sync process usually takes less then 20 seconds to complete
3
  • Hi! Did you resolve this somehow? Commented Nov 4, 2020 at 18:24
  • Not yet, I think you need to override onSyncCanceled and have your coroutine code check if cancel was called. I think that onSyncCanceled is called before the actual thread gets interrupted. So you need to honor this interruption. However I am currently migrating to WorkManager. Commented Nov 5, 2020 at 12:55
  • 1
    Thanks! I resorted to using runBlocking {} which works out fine. Android will create a new thread for the sync operation anyway, so it's good. Just need to make sure any of your internal suspend functions don't run on other threads. Commented Nov 6, 2020 at 13:12

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.