Search code examples
javaandroideclipsenetworkonmainthread

I am trying to get my application to connect to my server. But it throws these errors. How do I fix the MainThreadException?


04-02 21:59:03.086: E/log_tag(27382): Error in http connection android.os.NetworkOnMainThreadException
04-02 21:59:03.106: E/log_tag(27382): Error converting result java.lang.NullPointerException
04-02 21:59:03.106: E/log_tag(27382): Error parsing data org.json.JSONException: End of input at character 0 of 

From the following code:

package net.example.glutefree;

import android.app.Activity;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.TextView;

public class Networking extends Activity {
    TextView txt;
    int request_Code = 1;
//called when activity is first created
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_networking);
         // Create a crude view - this should really be set via the layout resources 
        // but since its an example saves declaring them in the XML. 
        LinearLayout rootLayout = new LinearLayout(getApplicationContext()); 
        txt = new TextView(getApplicationContext()); 
        rootLayout.addView(txt); 
        setContentView(rootLayout); 
        // Set the text and call the connect function. 
        txt.setText("Connecting...");
      //call the method to run the data retreival
        txt.setText(getServerData(KEY_121));
    }

    public static final String KEY_121 = "http://WEBSITE/application_query.php";

    private String getServerData(String returnString) {
       String UPC = getIntent().getStringExtra("UPCA");
       InputStream is = null;
       String result = "";
        //the upc data to send
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

        nameValuePairs.add(new BasicNameValuePair("UPCA",UPC));

        //http post
        try{

                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(KEY_121);
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();

        } catch(Exception e) {
                Log.e("log_tag", "Error in http connection "+e.toString());
        }

        //convert response to string
        try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                        sb.append(line + "\n");
                }
                is.close();
                result=sb.toString();
        } catch(Exception e) {
                Log.e("log_tag", "Error converting result "+e.toString());
        }
        //parse json data
        try {
                JSONArray jArray = new JSONArray(result);
                Log.e("log_tag", "Result "+result.toString()); 
                for(int i=0;i<jArray.length();i++) {
                        JSONObject json_data = jArray.getJSONObject(i);
                        Log.i("log_tag","UPCA: "+json_data.getString("UPCA")+
                                ", Product: "+json_data.getString("Product"));
                        //Get an output to the screen
                        returnString += "\n\t" + jArray.getJSONObject(i);
                }
        } catch(JSONException e) {
                Log.e("log_tag", "Error parsing data "+e.toString());
        }
        return returnString;
    }   

}

Solution

  • Use

    new Thread() {
        public void run() {
            final String data = getServerData(KEY_121);
            if (data != null)
                runOnUiThread(new Runnable()
                {
                    public void run()
                    {
                        txt.setText(data);
                    }
                });
        }
    }.start();
    

    Instead of:

     //call the method to run the data retreival
     txt.setText(getServerData(KEY_121));
    

    You cannot run long tasks on the main thread. But you have to use the UI thread to set the text.