title: NetworkOnMainThreadException in IntentService
body: <p>I am making network calls from an IntentService but still receiving a NetworkOnMainThreadException.  My understanding is that an IntentService always runs on a worker thread, so I'm suprised to see this.  The crucial piece may be that my IntentService is calling a static helper class that performs the network calls.  The static helper class is instantiated in my main Application class.  </p>
  
  <p>I thought this would still execute on the worker thread of the IntentService.  What am I missing?</p>
  
  <p>Honestly I prefer heady informative discussions over a quick code fix.  But if code is required, code shall be provided:</p>
  
  <pre><code>//MyApplication.java
  public class MyApplication extends Application{
  
  private static NetworkUtils utils;
  
      @Override
      public void onCreate() {
          super.onCreate();
          utils = new NetworkUtils(this);
          ...
      }
      ...
  }
  
  //NetworkUtils.java
  public class NetworkUtils {
  
      private static Context context;
      private static final Gson gson = new Gson();
  
      public NetworkUtils(Context context) {
          this.context = context;
      }
  
      public static final DataResponse login(String email, String password) {
          //*** NetworkOnMainThreadException OCCURS HERE ***
          DataResponse response = HttpConnection.put(url, json);
          ...
          return response;
      }
      ...
  }
  
  //LoginService.java
  public class LoginService extends IntentService {
  
      public LoginService() {
          super("LoginService");
      }
  
      @Override
      public void onStart(Intent intent, int startId) {
          onHandleIntent(intent);
      }
  
      @Override
      protected void onHandleIntent(Intent intent) {
          Bundle bundle = new Bundle();
          DataResponse response = NetworkUtils.login(email, password);
          ...
          bundle.putBoolean(MyConstants.ExtraKeys.LOGGED, response.success);
          MainApplication.getApplicationInstance().sendBroadCast(MyConstants.Actions.LOGIN, bundle);
      }
  }
  
  //LoginActivity.java
  public class LoginActivity extends ActionBarActivity implements IDialogClickListener {
      ...
      public void onLoginButtonPressed() {
          Intent intent = new Intent(MainApplication.getApplicationInstance(), LoginService.class);
          this.startService(intent);
      }
  }
  </code></pre>
  
  <p>Also, Logcat: </p>
  
  <pre><code>&gt; 04-01 18:20:41.048: VERBOSE/com.foo.foo(28942):
  &gt;     com.foo.foo.network.HttpConnection.execute - METHOD: PUT   
  &gt; 04-01 18:20:41.068: ERROR/com.foo.foo(28942):
  &gt;     com.foo.foo.social.NetworkUtils.login - class
  &gt;     android.os.NetworkOnMainThreadException:  null   
  &gt; 04-01 18:20:41.169: DEBUG/com.foo.foo(28942):
  &gt;     com.foo.foo.MainActivity$MyReceiver.onReceive - BROADCAST RECEIVED:
  &gt;     com.foo.foo.MainApplication@422d81d8 - Intent { act=com.foo.foo.login
  &gt;     dat=com.foo.foo.scheme://data/1364854841079 (has extras) }   
  &gt; 04-01 18:20:41.169: INFO/com.foo.foo(28942):
  &gt;     com.foo.foo.activity.LoginActivity.setData - ACTION: com.foo.foo.login
  &gt;     - ISERROR: true
  </code></pre>
  
  <p><strong>SOLUTION</strong></p>
  
  <p>The underlying issue was a bit of legacy code that was calling <code>onHandleIntent</code> explicitly. In LoginService.java above: </p>
  
  <pre><code>@Override 
  public void onStart(Intent intent, int startId) { 
      onHandleIntent(intent); 
  } 
  </code></pre>
  
  <p>This is causing the onHandleIntent code to run on the main thread, as it is being called from the onStart event (which apparently runs on main thread). </p>