android.os.NetworkOnMainThreadException

Refer to my old exercise "Read Text file from internet, using Java code": it a simple exercise to read something from internet. It can be download here in project form.

It work as expected, to display the text file from internet, for android:minSdkVersion="9" or older. But fail with android:minSdkVersion="10" or higher. It's a strange and interesting issue for me.

OK for android:minSdkVersion='9' or older



Fail for android:minSdkVersion='10' or higher


After investigated into the logcat, I found that it's Caused by: android.os.NetworkOnMainThreadException!

android.os.NetworkOnMainThreadException is a 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 (actually it fail in my exercise with API level 10). Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged.

The solution is to move the internet accessing code to a background thread, AsyncTask in my exercise.

package com.exercise.AndroidInternetTxt;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidInternetTxt extends Activity {

TextView textMsg, textPrompt;
final String textSource = "http://sites.google.com/site/androidersite/text.txt";


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textPrompt = (TextView)findViewById(R.id.textprompt);
textMsg = (TextView)findViewById(R.id.textmsg);

textPrompt.setText("Wait...");

new MyTask().execute();

/*
URL textUrl;

try {
textUrl = new URL(textSource);

BufferedReader bufferReader 
= new BufferedReader(new InputStreamReader(textUrl.openStream()));

String StringBuffer;
String stringText = "";
while ((StringBuffer = bufferReader.readLine()) != null) {
stringText += StringBuffer;   
}
bufferReader.close();

textMsg.setText(stringText);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
textMsg.setText(e.toString());   
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
textMsg.setText(e.toString());   
}

textPrompt.setText("Finished!");    
*/
}

private class MyTask extends AsyncTask<Void, Void, Void>{

String textResult;

@Override
protected Void doInBackground(Void... params) {

URL textUrl;

try {
textUrl = new URL(textSource);

BufferedReader bufferReader 
= new BufferedReader(new InputStreamReader(textUrl.openStream()));

String StringBuffer;
String stringText = "";
while ((StringBuffer = bufferReader.readLine()) != null) {
stringText += StringBuffer;   
}
bufferReader.close();

textResult = stringText;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
textResult = e.toString();   
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
textResult = e.toString();   
}

return null;

}

@Override
protected void onPostExecute(Void result) {

textMsg.setText(textResult);
textPrompt.setText("Finished!");  

super.onPostExecute(result);   
}

}
}


Download the files.

Another un-recommended approach: StrictMode.setThreadPolicy and StrictMode.ThreadPolicy.Builder

1 Response to "android.os.NetworkOnMainThreadException"

  1. Hi! This is kind of off topic but I need some help from an established blog.
    Is it very difficult to set up your own blog? I'm not very techincal but I can figure things out pretty fast. I'm thinking about creating
    my own but I'm not sure where to start. Do you have any tips or suggestions? Many thanks

    Here is my weblog swiftlyfitness.com

    ReplyDelete