-2

When i ran my Android Application, I got an android.os.NetworkOnMainThreadException error. I have also added the INTERNET permissions to the manifest file but still it shows this error. Please help advice on what to do. Thanks.

This is my logcat

03-06 11:40:55.721: W/dalvikvm(2142): threadid=1: thread exiting with uncaught exception (group=0x40014760)
03-06 11:40:55.740: E/AndroidRuntime(2142): FATAL EXCEPTION: main
03-06 11:40:55.740: E/AndroidRuntime(2142): android.os.NetworkOnMainThreadException
03-06 11:40:55.740: E/AndroidRuntime(2142):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1077)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at dalvik.system.BlockGuard$WrappedNetworkSystem.connect(BlockGuard.java:368)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:208)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.harmony.luni.net.PlainSocketImpl.connect(PlainSocketImpl.java:431)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at java.net.Socket.connect(Socket.java:901)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at com.example.testexternaldatabase.JSONParser.makeHttpRequest(JSONParser.java:62)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at com.example.testexternaldatabase.EditTicketActivity$GetProductDetails$1.run(EditTicketActivity.java:135)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at android.os.Handler.handleCallback(Handler.java:587)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at android.os.Handler.dispatchMessage(Handler.java:92)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at android.os.Looper.loop(Looper.java:132)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at android.app.ActivityThread.main(ActivityThread.java:4025)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at java.lang.reflect.Method.invokeNative(Native Method)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at java.lang.reflect.Method.invoke(Method.java:491)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
03-06 11:40:55.740: E/AndroidRuntime(2142):  at dalvik.system.NativeStart.main(Native Method)
This is my get_message_details.php file. This file is to accept input as a JSON Array and the messages table will be updated.

<?php


// array for JSON response
$response = array();


// include db connect class
require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

$_GET["pid"] = "1";

// check for post data
if (isset($_GET["pid"])) {
    $message_id = $_GET['pid'];

    // get a message from messages table
    $result = mysql_query("SELECT *FROM messages WHERE message_id = '".$message_id."'");

    if (!empty($result)) {
        // check for empty result
        if (mysql_num_rows($result) > 0) {

            $result = mysql_fetch_array($result);

            $message = array();
            $message["message_id"] = $result["message_id"];
            $message["subject"] = $result["subject"];
            $message["type"] = $result["type"];
            $message["description"] = $result["description"];
    
            $response["success"] = 1;

            // user node
            $response["message"] = array();

            array_push($response["message"], $message);

            // echoing JSON response
            echo json_encode($response);
        } else {
            // no message found
            $response["success"] = 0;
            $response["message"] = "No message found";

            // echo no users JSON
            echo json_encode($response);
        }
    } else {
        // no message found
        $response["success"] = 0;
        $response["message"] = "No message found";

        // echo no users JSON
        echo json_encode($response);
    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>




This is my EditTicketActivity.java class.
package com.example.testexternaldatabase;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.*;

public class EditTicketActivity extends Activity {

 EditText txtSubject;
 EditText txtType;
 EditText txtDesc;
 Button btnSave;
 Button btnDelete;

 String pid;

 // Progress Dialog
 private ProgressDialog pDialog;

 // JSON parser class
 JSONParser jsonParser = new JSONParser();

 static GetIPAddress getIPaddress = new GetIPAddress();
  
 // single product url
 private static String url_product_details = getIPaddress.getIP()+"get_message_details.php";;

 // url to update product
 private static String url_update_product = getIPaddress.getIP()+"update_message.php";
 
 // url to delete product
 private static String url_delete_product = getIPaddress.getIP()+"delete_message.php";

 // JSON Node names
 private static final String TAG_SUCCESS = "success";
 private static final String TAG_PRODUCT = "message";
 private static final String TAG_PID = "message_id";
 private static final String TAG_NAME = "subject";
 private static final String TAG_PRICE = "type";
 private static final String TAG_DESCRIPTION = "description";

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.edit_ticket);

  //url_product_details = getIPaddress.getIP()+"get_message_details.php";
  //url_update_product = getIPaddress.getIP()+"update_message.php";
  //url_delete_product = getIPaddress.getIP()+"delete_message.php";
  
  // save button
  btnSave = (Button)findViewById(R.id.editticket_save);
  btnDelete = (Button)findViewById(R.id.editticket_delete);

  // getting product details from intent
  Intent i = getIntent();
  
  // getting product id (pid) from intent
  pid = i.getStringExtra(TAG_PID);

  // Getting complete product details in background thread
  new GetProductDetails().execute();

  // save button click event
  btnSave.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View arg0) {
    // starting background task to update product
    new SaveProductDetails().execute();
   }
  });

  // Delete button click event
  btnDelete.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View arg0) {
    // deleting product in background thread
    new DeleteProduct().execute();
   }
  });

 }

 /**
  * Background Async Task to Get complete product details
  * */
 class GetProductDetails extends AsyncTask<String, String, String> {

  /**
   * Before starting background thread Show Progress Dialog
   * */
  @Override
  protected void onPreExecute() {
   super.onPreExecute();
   pDialog = new ProgressDialog(EditTicketActivity.this);
   pDialog.setMessage("Loading Tickets. 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", pid));

      // getting product details by making HTTP request
      // Note that product details url will use GET request
      JSONObject json = jsonParser.makeHttpRequest(
        url_product_details, "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 messageObj = json
         .getJSONArray(TAG_PRODUCT); // JSON Array
       
       // get first product object from JSON Array
       JSONObject message = messageObj.getJSONObject(0);

       // product with this pid found
       // Edit Text
       txtSubject = (EditText) findViewById(R.id.editticket_subject);
       txtType = (EditText) findViewById(R.id.editticket_type);
       txtDesc = (EditText) findViewById(R.id.editticket_description);

       // display product data in EditText
       txtSubject.setText(message.getString(TAG_NAME));
       txtType.setText(message.getString(TAG_PRICE));
       txtDesc.setText(message.getString(TAG_DESCRIPTION));

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

   return null;
  }


  /**
   * After completing background task Dismiss the progress dialog
   * **/
  protected void onPostExecute(String file_url) {
   // dismiss the dialog once got all details
   pDialog.dismiss();
  }
 }

 /**
  * Background Async Task to  Save product Details
  * */
 class SaveProductDetails extends AsyncTask<String, String, String> {

  /**
   * Before starting background thread Show Progress Dialog
   * */
  @Override
  protected void onPreExecute() {
   super.onPreExecute();
   pDialog = new ProgressDialog(EditTicketActivity.this);
   pDialog.setMessage("Saving product ...");
   pDialog.setIndeterminate(false);
   pDialog.setCancelable(true);
   pDialog.show();
  }

  /**
   * Saving product
   * */
  protected String doInBackground(String... args) {

   // getting updated data from EditTexts
   String subject = txtSubject.getText().toString();
   String type = txtType.getText().toString();
   String description = txtDesc.getText().toString();

   // Building Parameters
   List<NameValuePair> params = new ArrayList<NameValuePair>();
   params.add(new BasicNameValuePair(TAG_PID, pid));
   params.add(new BasicNameValuePair(TAG_NAME, subject));
   params.add(new BasicNameValuePair(TAG_PRICE, type));
   params.add(new BasicNameValuePair(TAG_DESCRIPTION, description));

   // sending modified data through http request
   // Notice that update product url accepts POST method
   JSONObject json = jsonParser.makeHttpRequest(url_update_product,
     "POST", params);

   // check json success tag
   try {
    int success = json.getInt(TAG_SUCCESS);
    
    if (success == 1) {
     // successfully updated
     Intent i = getIntent();
     // send result code 100 to notify about product update
     setResult(100, i);
     finish();
    } else {
     // failed to update product
    }
   } catch (JSONException e) {
    e.printStackTrace();
   }

   return null;
  }


  /**
   * After completing background task Dismiss the progress dialog
   * **/
  protected void onPostExecute(String file_url) {
   // dismiss the dialog once product uupdated
   pDialog.dismiss();
  }
 }

 /*****************************************************************
  * Background Async Task to Delete Product
  * */
 class DeleteProduct extends AsyncTask<String, String, String> {

  /**
   * Before starting background thread Show Progress Dialog
   * */
  @Override
  protected void onPreExecute() {
   super.onPreExecute();
   pDialog = new ProgressDialog(EditTicketActivity.this);
   pDialog.setMessage("Deleting Product...");
   pDialog.setIndeterminate(false);
   pDialog.setCancelable(true);
   pDialog.show();
  }

  /**
   * Deleting product
   * */
  protected String doInBackground(String... args) {

   // Check for success tag
   int success;
   try {
    // Building Parameters
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("pid", pid));

    // getting product details by making HTTP request
    JSONObject json = jsonParser.makeHttpRequest(
      url_delete_product, "POST", params);

    // check your log for json response
    Log.d("Delete Product", json.toString());
    
    // json success tag
    success = json.getInt(TAG_SUCCESS);
    if (success == 1) {
     // product successfully deleted
     // notify previous activity by sending code 100
     Intent i = getIntent();
     // send result code 100 to notify about product deletion
     setResult(100, i);
     finish();
    }
   } catch (JSONException e) {
    e.printStackTrace();
   }

   return null;
  }

  /**
   * After completing background task Dismiss the progress dialog
   * **/
  protected void onPostExecute(String file_url) {
   // dismiss the dialog once product deleted
   pDialog.dismiss();

  }

 }
}

What am I doing wrong here and how could I fix it? :) Thanks!!

  • 2
    The goal of using an asynctask is to perform tasks on another thread than the UI thread, but you're using `runOnUiThread(` in your `doInBackground` method which defeats the purpose of it(and hence the NetworkOnMainThread error). Do the busy stuff in `doInBackground` and update the UI in the `onPostExecute` method – Alexis C. Mar 07 '15 at 17:06
  • so do i have to remove the runOnUiThread(new Runnable()) – Williams Tobi Mar 07 '15 at 17:22

1 Answers1

0

You should not use UI element in Asynctask doInBackground() method. Move all UI updation code to onPostExecute() method of the AsyncTask

Example you can refer

AsyncTask Android example

Community
  • 1
  • 1
Fahim
  • 12,198
  • 5
  • 39
  • 57