title: On which thread does onReceive() of a BroacastReceiver registered with LocalBroadcastManager run?
body: <p>I register a broadcast receiver in a preference activity and send it a (sync) broadcast from a (Wakeful) IntentService. Apparently onReceive runs on the service's thread. Is this a fault of my part ? Is it documented behavior ?</p>
  
  <p>Preference activity:</p>
  
  <pre><code>public final class SettingsActivity extends BaseSettings {
  
      private static CharSequence sMasterKey;
      private CheckBoxPreference mMasterPref;
      // Receiver
      /** If the master preference is changed externally this reacts */
      private BroadcastReceiver mExternalChangeReceiver =
          new ExternalChangeReceiver();
  
      public static void notifyMonitoringStateChange(Context ctx,
              CharSequence action, boolean isToggling) {
          final LocalBroadcastManager lbm = LocalBroadcastManager
              .getInstance(ctx);
          Intent intent = new Intent(ctx, ExternalChangeReceiver.class);
          intent.setAction(action.toString());
          intent.putExtra(TOGGLING_MONITORING_IN_PROGRESS, isToggling);
          lbm.sendBroadcastSync(intent);
      }
  
      @Override
      protected void onStart() {
          super.onStart();
          final LocalBroadcastManager lbm = LocalBroadcastManager
              .getInstance(this);
          lbm.registerReceiver(mExternalChangeReceiver, new IntentFilter(
              ac_toggling.toString()));
      }
  
      @Override
      protected void onStop() {
          // may not be called in Froyo
          final LocalBroadcastManager lbm = LocalBroadcastManager
              .getInstance(this);
          lbm.unregisterReceiver(mExternalChangeReceiver);
          super.onStop();
      }
  
      private final class ExternalChangeReceiver extends BroadcastReceiver {
  
          ExternalChangeReceiver() {}
  
          @Override
          @SuppressWarnings("synthetic-access")
          public void onReceive(Context ctx, Intent intent) {
              if (sMasterKey == null || mMasterPref == null) return; // if
              // onPostReceive has not run this will be null
              final String action = intent.getAction();
              if (ac_toggling.equals(action)) {
                  final boolean isToggling = intent.getBooleanExtra(
                      TOGGLING_MONITORING_IN_PROGRESS, false);
                  Log.w(ExternalChangeReceiver.class.getSimpleName(),
                      "isToggling " + isToggling);
                  mMasterPref.setEnabled(!isToggling); // line 168 !!!
                  refreshMasterPreference(isToggling);
              }
          }
      }
  }
  </code></pre>
  
  <p>IntentService (LocationMonitor):</p>
  
  <pre><code>SettingsActivity.notifyMonitoringStateChange(this, ac_toggling, true);
  </code></pre>
  
  <p>Exception (E/AndroidRuntime):</p>
  
  <pre><code>FATAL EXCEPTION: IntentService[LocationMonitor]
  android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
      at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746)
      at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:823)
      at android.view.View.requestLayout(View.java:15473)
      at android.view.View.requestLayout(View.java:15473)
      at android.view.View.requestLayout(View.java:15473)
      at android.view.View.requestLayout(View.java:15473)
      at android.view.View.requestLayout(View.java:15473)
      at android.view.View.requestLayout(View.java:15473)
      at android.view.View.requestLayout(View.java:15473)
      at android.view.View.requestLayout(View.java:15473)
      at android.view.View.requestLayout(View.java:15473)
      at android.widget.AbsListView.requestLayout(AbsListView.java:1819)
      at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:813)
      at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:5958)
      at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
      at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
      at android.preference.PreferenceGroupAdapter.onPreferenceChange(PreferenceGroupAdapter.java:238)
      at android.preference.Preference.notifyChanged(Preference.java:1099)
      at android.preference.Preference.setEnabled(Preference.java:726)
      at gr.uoa.di.monitoring.android.activities.SettingsActivity$ExternalChangeReceiver.onReceive(SettingsActivity.java:168)
      at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
      at android.support.v4.content.LocalBroadcastManager.sendBroadcastSync(LocalBroadcastManager.java:278)
      at gr.uoa.di.monitoring.android.activities.SettingsActivity.notifyMonitoringStateChange(SettingsActivity.java:54)
      at gr.uoa.di.monitoring.android.services.Monitor.abort(Monitor.java:241)
      at gr.uoa.di.monitoring.android.services.LocationMonitor.doWakefulWork(LocationMonitor.java:103)
      at com.commonsware.cwac.wakeful.WakefulIntentService.onHandleIntent(WakefulIntentService.java:94)
      at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
      at android.os.Handler.dispatchMessage(Handler.java:99)
      at android.os.Looper.loop(Looper.java:137)
      at android.os.HandlerThread.run(HandlerThread.java:60)
  </code></pre>
  
  <p>On an emulator API 17</p>