Do callbacks occur on the main (UI) thread?

There are a lot of Android SDK APIs where callback handlers are registered. For a concrete example, with MediaPlayer you can set an onCompletionListener callback. Will these callbacks be called from the main (UI) thread? If the answer is “it depends”, then I’m looking for some general rules for what callbacks will be called from the main thread versus another thread. The SDK documentation doesn’t seem to spell it out. (Maybe I missed it.)

It seems important to know, because if I’m guaranteed main thread callbacks, then I can skip some thread synchronization on data shared between different places in code. If I’m forced to be pessimistic out of ignorance, then I have to write extra synch block code and worry about deadlocks, data integrity, and reduced performance.

  • Where to get database error information in Android SQLite (e.g. failed insert due to violation of not null)
  • Broadcast charger disconnected in Android O
  • Android eclipse startManagingCursor Deprecated but want to support older API versions?
  • Button to go back to MainActivity
  • Is it possible to access the current Fragment being viewed by a ViewPager?
  • ArrayAdapter:you must supply a resource id for a textview
  • Related posts:

    ViewPager inside a ScrollView does not scroll correclty
    Enabling WiFi on Android Emulator
    error: cannot find symbol method getMap() after dependencies update
    How to Synchronize Android Database with an online SQL Server?
    Using Espresso to Unit Test Google Maps
    Androind 2.2 Preview 1 - Using ConstraintsLayout with GuideLine app crashes
  • Advantages of using Binder for IPC in Android
  • Creating animation for images from small to large when scrolling vertical
  • Android Eclipse Plugin: Instrumentation Test Runner not specified
  • Android: Programmatically open “Recent Apps” dialog
  • Sticky Header RecyclerView with multiple ArrayLists
  • How to check if an Android Thread is running
  • 6 Solutions collect form web for “Do callbacks occur on the main (UI) thread?”

    One case where Android will call your code on some other thread will be if you create a remote service, exposed via AIDL — those AIDL methods will be called on a binder thread, not the main application thread.

    However, that is the exception. As the others have noted, the vast majority of these are called on the main application thread.

    When in doubt you can use Log.i("TAG", Thread.currentThread().getName()); and see 🙂

    In my experience, those callbacks always come back on a non-UI thread. Have you tried Activity.runOnUiThread() to make sure your code runs on the UI thread? You would still take the performance hit because it takes longer for this code to run, but you would avoid some of the more common problems with thread synchronization.

    In general, the callbacks will occur on the thread where the event is running. If you register a callback and start something playing on a non-UI thread, then the callback will occur on the non-UI thread. However, Android won’t go creating new threads in the background on its own.

    All UI related events must occur on the UI thread, so you can gauarentee that click handler callbacks, etc will occur on the UI thread.

    As Aaron C pointed out, you can use Activity.runOnUiThread to force things to occur there.

    Additionally, the AsyncTask can be very useful for doing quick background work, where you need some completion step to be gauranteed to be on the uI thread.

    edit: Example from the comments.

    public void MyWorker {
       private OnCompleteListener onCompleteListener;
    
       public void setOnCompleteListener(OnCompleteListener onCompleteListener) {
         this.onCompleteListener = onCompleteListener;
       }
    
       public void doWork() {
         // do lots of work here
         onCompleteListener.onComplete();
       }
    }
    
    // somewhere in my Activity
    
    public void onCreate() {
       final MyWorker worker = new MyWorker();
       worker.setOnCompleteListener(new OnCompleteListener() { ... });
    
       new Thread(new Runnable() {
           public void run() {
              worker.doWork();
           }
       }).start();
    }
    

    In this example, the onComplete “callback” will be run from the non-UI thread. The thread will exit after onComplete finishes.

    Another exception is the When you are using WebView. When javascript calling a Java function, such invocation will not happen in main thread

    Something similar came up when I was working on Location APIs. As we know, we provide a callback for Location services, so that we get notified once we have acquired a location.
    So I was doing something in this callback which were taking a long time like using Geocoder APIs.

    I was under impression before that, this callback would be called from other thread and thus would not be executed on main UI thread. But I can see, its not the case.

    So what ever code I write in this listener will be executed on the main thread.

    Now what I don’t understand is how do they manage to do that, is it by using a standerd function runOnUIThread() ???

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.