Android invasion, Sydney, Australia

In this article I explain a possible cause of android.os.NetworkOnMainThreadException and how to avoid it.
From the Android site you can read:
NetworkOnMainThreadException
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or higher…

Here is a sample developed for Gingerbread, API level 9:

  1. create an Android project called HttpClient
  2. edit the file AndroidManifest.xml
    1 <?xml version="1.0" encoding="utf-8"?>
    2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    3     package="eu.lucazanini.httpclient"
    4     android:versionCode="1"
    5     android:versionName="1.0" >
    6
    7     <uses-sdk android:minSdkVersion="9" />
    8     <uses-permission android:name="android.permission.INTERNET"/>
    9
    10     <application
    11         android:icon="@drawable/ic_launcher"
    12         android:label="@string/app_name" >
    13         <activity
    14             android:name=".HttpClientActivity"
    15             android:label="@string/app_name" >
    16             <intent-filter>
    17                 <action android:name="android.intent.action.MAIN" />
    18
    19                 <category android:name="android.intent.category.LAUNCHER" />
    20             </intent-filter>
    21         </activity>
    22     </application>
    23
    24 </manifest>

    where <uses-sdk android:minSdkVersion=”9″ /> means an API version earlier to Honeycomb (Gingerbread, API level 9), and <uses-permission android:name=”android.permission.INTERNET”/> authorizes the application to perform an internet connection

  3. edit the file HttpClientActivity.java
    1 package eu.lucazanini.httpclient;
    2
    3 import java.io.IOException;
    4
    5 import org.apache.http.HttpResponse;
    6 import org.apache.http.client.ClientProtocolException;
    7 import org.apache.http.client.methods.HttpGet;
    8 import org.apache.http.impl.client.DefaultHttpClient;
    9
    10 import android.app.Activity;
    11 import android.os.Bundle;
    12 import android.util.Log;
    13
    14 public class HttpClientActivity extends Activity {
    15
    16     @Override
    17     public void onCreate(Bundle savedInstanceState) {
    18         super.onCreate(savedInstanceState);
    19         setContentView(R.layout.main);
    20
    21         connect();
    22
    23     }
    24
    25     private void connect() {
    26         try {
    27             DefaultHttpClient client = new DefaultHttpClient();
    28             HttpGet request = new HttpGet("http://www.google.com");
    29             HttpResponse response = client.execute(request);
    30         } catch (ClientProtocolException e) {
    31             Log.d("HTTPCLIENT", e.getLocalizedMessage());
    32         } catch (IOException e) {
    33             Log.d("HTTPCLIENT", e.getLocalizedMessage());
    34         }
    35     }
    36
    37 }

This app is executed without errors.

If you specify an API level after Honeycomb, such as Ice Cream Sandwich, replacing the line <uses-sdk android:minSdkVersion=”9″ /> with <uses-sdk android:minSdkVersion=”14″ /> and you launch the application, you get the exception android.os.NetworkOnMainThreadException.

An easy way to avoid the exception is to insert the following code (which requires import android.os.StrictMode):

1 StrictMode.ThreadPolicy policy = new
2 StrictMode.ThreadPolicy.Builder()
3 .permitAll().build();
4 StrictMode.setThreadPolicy(policy);

before the row connect() in HttpClientActivity.java
But this method is recommended in development environments only, the recommended method is to use the class AsyncTask.

An example is the following in which the code of the class HttpClientActivity.java is replaced by:

1 package eu.lucazanini.httpclient;
2
3 import java.io.IOException;
4
5 import org.apache.http.HttpResponse;
6 import org.apache.http.client.ClientProtocolException;
7 import org.apache.http.client.methods.HttpGet;
8 import org.apache.http.impl.client.DefaultHttpClient;
9
10 import android.app.Activity;
11 import android.os.AsyncTask;
12 import android.os.Bundle;
13 //import android.os.StrictMode;
14 import android.util.Log;
15
16 public class HttpClientActivity extends Activity {
17     /** Called when the activity is first created. */
18     @Override
19     public void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.main);
22
23 //      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
24 //              .permitAll().build();
25 //      StrictMode.setThreadPolicy(policy);
26
27 //      connect();
28
29         new Connection().execute();
30
31     }
32
33     private class Connection extends AsyncTask {
34
35         @Override
36         protected Object doInBackground(Object... arg0) {
37             connect();
38             return null;
39         }
40
41     }
42
43     private void connect() {
44         try {
45             DefaultHttpClient client = new DefaultHttpClient();
46             HttpGet request = new HttpGet("http://www.google.com");
47             HttpResponse response = client.execute(request);
48         } catch (ClientProtocolException e) {
49             Log.d("HTTPCLIENT", e.getLocalizedMessage());
50         } catch (IOException e) {
51             Log.d("HTTPCLIENT", e.getLocalizedMessage());
52         }
53     }
54
55 }

You can override not only doInBackground but also other methods of the AsyncTask class like OnPreExecute(), OnPostExecute(Result), publishProgress(Progress. ..).

Advertisements
Comments
  1. Atif Rana says:

    its good really helped me alot 🙂

    Like

  2. Moin Ramiz says:

    thank you for sharing it 🙂

    Like

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s