-2

Im learning the JSON Parser. I follow the androidhive tutorial and copy its code, but sadly, i cannot. It does not display anything and has these type of errors:

 11-22 17:27:12.132: E/AndroidRuntime(1938): Caused by: android.os.NetworkOnMainThreadException

Can anyone help me with this problem? Thanks.

JSONPaser

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    // constructor
    public JSONParser() {

    }

    public JSONObject getJSONFromUrl(String url) {

        // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();           

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        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();
            json = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;

    }
}

MainActivity

import android.view.Menu;

import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;


public class MainActivity extends ListActivity{
    // url to make request
        private static String url = "http://api.androidhive.info/contacts/";

        // JSON Node names
        private static final String TAG_CONTACTS = "contacts";
        private static final String TAG_ID = "id";
        private static final String TAG_NAME = "name";
        private static final String TAG_EMAIL = "email";
        private static final String TAG_ADDRESS = "address";
        private static final String TAG_GENDER = "gender";
        private static final String TAG_PHONE = "phone";
        private static final String TAG_PHONE_MOBILE = "mobile";
        private static final String TAG_PHONE_HOME = "home";
        private static final String TAG_PHONE_OFFICE = "office";

        // contacts JSONArray
        JSONArray contacts = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Hashmap for ListView
                ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();

                // Creating JSON Parser instance
                JSONParser jParser = new JSONParser();

                // getting JSON string from URL
                JSONObject json = jParser.getJSONFromUrl(url);

                try {
                    // Getting Array of Contacts
                    contacts = json.getJSONArray(TAG_CONTACTS);

                    // looping through All Contacts
                    for(int i = 0; i < contacts.length(); i++){
                        JSONObject c = contacts.getJSONObject(i);

                        // Storing each json item in variable
                        String id = c.getString(TAG_ID);
                        String name = c.getString(TAG_NAME);
                        String email = c.getString(TAG_EMAIL);
                        String address = c.getString(TAG_ADDRESS);
                        String gender = c.getString(TAG_GENDER);

                        // Phone number is agin JSON Object
                        JSONObject phone = c.getJSONObject(TAG_PHONE);
                        String mobile = phone.getString(TAG_PHONE_MOBILE);
                        String home = phone.getString(TAG_PHONE_HOME);
                        String office = phone.getString(TAG_PHONE_OFFICE);

                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();

                        // adding each child node to HashMap key => value
                        map.put(TAG_ID, id);
                        map.put(TAG_NAME, name);
                        map.put(TAG_EMAIL, email);
                        map.put(TAG_PHONE_MOBILE, mobile);

                        // adding HashList to ArrayList
                        contactList.add(map);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }


                /**
                 * Updating parsed JSON data into ListView
                 * */
                ListAdapter adapter = new SimpleAdapter(this, contactList,
                        R.layout.list_item,
                        new String[] { TAG_NAME, TAG_EMAIL, TAG_PHONE_MOBILE }, new int[] {
                                R.id.name, R.id.email, R.id.mobile });

                setListAdapter(adapter);

                // selecting single ListView item
                ListView lv = getListView();

                // Launching new screen on Selecting Single ListItem
                lv.setOnItemClickListener(new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
                        // getting values from selected ListItem
                        String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
                        String cost = ((TextView) view.findViewById(R.id.email)).getText().toString();
                        String description = ((TextView) view.findViewById(R.id.mobile)).getText().toString();

                        // Starting new intent
                        Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
                        in.putExtra(TAG_NAME, name);
                        in.putExtra(TAG_EMAIL, cost);
                        in.putExtra(TAG_PHONE_MOBILE, description);
                        startActivity(in);

                    }
                });


            }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

<uses-permission android:name="android.permission.INTERNET" /> is use in Manifest

How can i use AsyncTask or Thread with Handler to solve the error ?? do i need to delete my JSON Parser class ??

things i tried so far:

  • i switched i target SDK version to fit my emulator but it still doesn't work
  • i run the project on my phone (Samsung) and emulator (Genymotion) it show the same error
  • i tried to test another method without JSON Array

    import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.TextView; import android.util.Log;

    import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader;

    import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient;

    public class Main extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        try{ //try1 start
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        // this is our TextView element, obtained by id from our XML layout
        TextView myListView = (TextView)findViewById(R.id.netResult);
    
        //lets try to connect
            try{ //try2 start
    
            //create a new client object
            HttpClient httpclient = new DefaultHttpClient();
    
            HttpPost httppost = new HttpPost("http://ephemeraltech.com/demo/android_tutorial20.php");
    
            //execute the post and get the response object
            HttpResponse response = httpclient.execute(httppost);
    
            //get the message from the response 
            HttpEntity entity = response.getEntity();
    
            //get the content of the message
            InputStream webs = entity.getContent();
    
            //convert response to string
                    try{ //try3 start
                    BufferedReader reader = new BufferedReader(new InputStreamReader(webs,"utf-8"),8);
    
                    //read one line of the response
                    myListView.setText(reader.readLine());
    
                    //slow our inputStream
                    webs.close();
                    }//try3 end
            catch (Exception e){//catch 3 start 
                Log.e("log_result", "Error converting result "+e.toString());
            }//catch 3 end
    
            } //try2 end
            catch (Exception e){//catch 2 start
                Log.e("log_connect", "Error in http connection "+e.toString());
            }
        }//try1 end
        catch (Exception e){ //catch 1 start
            //this is the lie of code that sends a real error message to the log
            Log.e("ERROR", "ERROR IN CODE: "+e.toString());
            e.printStackTrace();
        }//catch 1 end
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    

    }

in this code the LogCat catch my second try and print log_connect, Error in http connection

Jing
  • 3
  • 7
  • to improve your question, better show the `Code`.. what you did to get the error, what you already tried, the link to the tutorial that you used to did it.. etc. – Paulo Roberto Rosa Nov 22 '13 at 10:44
  • possible duplicate of [android.os.NetworkOnMainThreadException](http://stackoverflow.com/questions/6343166/android-os-networkonmainthreadexception) – Bryan Herbst Nov 22 '13 at 16:12
  • I'm sorry i don't understand the meaning of off topic. I'm new and i learning android without proper guidance, i can't define the problem. Please forgive my foolishness and help mi with this problem thank you – Jing Nov 23 '13 at 07:19

2 Answers2

0

You have a NetworkOnMainThreadException error.

That means you have directly run your code on onCreate method:

But you can't update your data directly on MainUI thread.

For that you have to use AsyncTask or Thread with Handler or update your UI with runOnUiThread()

You can go with this: http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html

Piyush
  • 18,895
  • 5
  • 32
  • 63
0

Did you read the stack trace at all?

Caused by: android.os.NetworkOnMainThreadException

If you had even googled with "NetworkOnMainThreadException" you would have got the answer.

In short, the reason is you are performing an HTTP request on the main thread which is a bad practise actually. Android recently has become more restrictive and throws an exception.

What you need is something like this:

new AsyncTask<CustomParamClass, Void, String>() {
    @Override
    protected String doInBackground(final CustomerParamClass... params) {
        //use params to get the data and make an HHTP Request.
    }

    @Override
    protected void onPostExecute(final String params) {
        // This is invoked on the main thread. Communicate here.
    }
}.execute(<pass some params here>);
UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
  • sry im new in android , just started learning last month. But where should i put this method ?? main class or JSON Parser class – Jing Nov 22 '13 at 10:36
  • you should put this method in your main class at where you can execute this class. – Piyush Nov 22 '13 at 10:48