Alex Lungu
Alex Lungu

Reputation: 1114

Why does this give a NetworkOnMainThreadException?

I'm trying to get the details of a product from a MySQL database but when I compile the code I get a NetworkOnMainThreadException error even if I use the class GetProductDetails as AsyncTask when I call it to execute . I don't really understand why this happens since I was following a tutorial to do it and I don't see any error.

This is the code that i'm using:

public class ListClubs extends Activity {

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_clubs);  
new GetProductDetails().execute(); 

(...some code...)    
}

class GetProductDetails extends AsyncTask<String, String, String> {
      @Override
      protected void onPreExecute() {
          super.onPreExecute();
          pDialog = new ProgressDialog(ListClubs.this);
          pDialog.setMessage("Loading product details. Please wait...");
          pDialog.setIndeterminate(false);
          pDialog.setCancelable(true);
          pDialog.show();
      }
    /**
     * Getting product details in background thread
     * */
    protected String doInBackground(String... params) {

        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {
                // Check for success tag
                int success;
                try {
                    // Building Parameters
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    params.add(new BasicNameValuePair("pid", Integer.toString(1))); 

                    // getting product details by making HTTP request
                    // Note that product details url will use GET request
                    JSONObject json = jsonParser.makeHttpRequest(url_product_detials, "GET", params);

                    // check your log for json response
                    Log.d("Single Product Details", json.toString());

                    // json success tag
                    success = json.getInt(TAG_SUCCESS);
                    if (success == 1) {
                        // successfully received product details
                        JSONArray productObj = json.getJSONArray(TAG_PRODUCT); // JSON Array

                        // get first product object from JSON Array
                        JSONObject product = productObj.getJSONObject(0);

                    }else{
                        // product with pid not found
                    } 
                } catch (JSONException e) {
                    e.printStackTrace();
                } 
            }
        });

        return null;
    }

    protected void onPostExecute(String file_url) {
        // dismiss the dialog once got all details
        pDialog.dismiss();
    }

 }

And this is the log:

FATAL EXCEPTION: main
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
at com.goout.JSONParser.makeHttpRequest(JSONParser.java:62)
at com.goout.ListClubs$GetProductDetails$1.run(ListClubs.java:464)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5227)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
at dalvik.system.NativeStart.main(Native Method)

Thanks!

Upvotes: 0

Views: 952

Answers (2)

Machinarius
Machinarius

Reputation: 3731

You are marshalling all your code at once from the AsyncTask into the main UI again, that's why right now it's as if the AsyncTask didn't exist, everything is ran from the UI Thread.

Extract your network code to run in the doInBackground method and return a meaningful (To your application) type from it, then override the onPostExecute method with the code that updates the UI with the result of doInBackground. onPostExceute is ALWAYS run from the Ui thread, you don't need to manage the threading yourself if you use it correctly.

More info: http://developer.android.com/reference/android/os/AsyncTask.html

Upvotes: 0

codeMagic
codeMagic

Reputation: 44571

Take this stuff out of doInbackground() and see what happens

 runOnUiThread(new Runnable() {
        public void run() {

The point of an AsyncTask is to run network stuff or any heavy lifting in doInBackground() then use the other methods to update the UI if needed. So you don't want to do the opposite of its purpose to tell its background code(doInbackground()) to run on the UI Thread with runOnUiThread().

Also, really good information on AsyncTask Here

Upvotes: 1

Related Questions