0

I am new to android application development. I was doing this tutorial app. When I run it in the emulator ,it says "Unfortunately AndroidJSONParsingActivity has stopped working. " There are no errors in the code. The API level is 17 and the emulator is Nexus S. Please help me out.

I got the tutorial CODE from JSON tutorial

AndroidJsonParsing.java

package com.example.androidjsonparsingactivity;

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 AndroidJSONParsing 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
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.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); 
        } 
    }); 
} 

}

JSONParser.java

package com.example.androidjsonparsingactivity;

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; 

}
}

SingleMenuItemActivity.java

package com.example.androidjsonparsingactivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class SingleMenuItemActivity  extends Activity {

// JSON node keys
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";
private static final String TAG_PHONE_MOBILE = "mobile";
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.single_list_item);

    // getting intent data
    Intent in = getIntent();

    // Get JSON values from previous intent
    String name = in.getStringExtra(TAG_NAME);
    String cost = in.getStringExtra(TAG_EMAIL);
    String description = in.getStringExtra(TAG_PHONE_MOBILE);

    // Displaying all values on the screen
    TextView lblName = (TextView) findViewById(R.id.name_label);
    TextView lblCost = (TextView) findViewById(R.id.email_label);
    TextView lblDesc = (TextView) findViewById(R.id.mobile_label);

    lblName.setText(name);
    lblCost.setText(cost);
    lblDesc.setText(description);
}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidjsonparsingactivity"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.androidjsonparsingactivity.AndroidJSONParsing"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".SingleListItem"
                android:label="Single Item Selected"></activity> 

</application>


</manifest>

Logcat

08-01 07:32:35.531: D/dalvikvm(1121): GC_FOR_ALLOC freed 42K, 7% free 2609K/2792K, paused 37ms, total 41ms
08-01 07:32:35.541: I/dalvikvm-heap(1121): Grow heap (frag case) to 3.288MB for 635812-byte allocation
08-01 07:32:35.591: D/dalvikvm(1121): GC_FOR_ALLOC freed 2K, 6% free 3227K/3416K, paused 47ms, total 47ms
08-01 07:32:35.672: D/dalvikvm(1121): GC_CONCURRENT freed <1K, 6% free 3237K/3416K, paused 9ms+16ms, total 82ms
08-01 07:32:35.740: D/AndroidRuntime(1121): Shutting down VM
08-01 07:32:35.740: W/dalvikvm(1121): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
08-01 07:32:35.761: E/AndroidRuntime(1121): FATAL EXCEPTION: main
08-01 07:32:35.761: E/AndroidRuntime(1121): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.androidjsonparsingactivity/com.example.androidjsonparsingactivity.AndroidJSONParsing}: android.os.NetworkOnMainThreadException
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.os.Looper.loop(Looper.java:137)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.app.ActivityThread.main(ActivityThread.java:5041)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at java.lang.reflect.Method.invokeNative(Native Method)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at java.lang.reflect.Method.invoke(Method.java:511)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at dalvik.system.NativeStart.main(Native Method)
08-01 07:32:35.761: E/AndroidRuntime(1121): Caused by: android.os.NetworkOnMainThreadException
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at java.net.InetAddress.getAllByName(InetAddress.java:214)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at com.example.androidjsonparsingactivity.JSONParser.getJSONFromUrl(JSONParser.java:38)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at com.example.androidjsonparsingactivity.AndroidJSONParsing.onCreate(AndroidJSONParsing.java:54)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.app.Activity.performCreate(Activity.java:5104)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
08-01 07:32:35.761: E/AndroidRuntime(1121):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
08-01 07:32:35.761: E/AndroidRuntime(1121):     ... 11 more

3 Answers3

3

For Android 4.0 and above you cant do network operations on UI Thread and need to use background threads.

You are calling the following code from the main thread instead of background thread therefore this exception is thrown .

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

Instead create a async task and perform this in the doInBackground() of the async task

Async task performs the opertaion in background instead of performing it on the main /UI thread

class FetchJsonTask extends AsyncTask<Void, Void, void> {


    protected Void doInBackground(Void... params) {
        try {
             // getting JSON string from URL 
        JSONObject json = jParser.getJSONFromUrl(url); 
        } catch (Exception e) {

        }
    }

    protected void onPostExecute(Void result) {
         super.onPostExecute(result);
       //code to be executed after background task is finished
    }


     protected void onPreExecute() {
         super.onPreExecute();
      //code to be executed before background task is started
     }
  return null;
}

In onCreate() call the execute the async task in the following way :

new FetchJsonTask().execute(); 

Related Link:

How to fix android.os.NetworkOnMainThreadException?

Community
  • 1
  • 1
Rachita Nanda
  • 4,509
  • 9
  • 42
  • 66
  • i really appreciate your help! – user2640948 Aug 01 '13 at 09:02
  • But i am very new in android I cant figure out the link u posted. Could u please code it in details Thank u very much! – user2640948 Aug 01 '13 at 09:04
  • what problem are you facing now ? all you have to do is create a aync task in the way I have done and add the code that accesses the network in the do in background ,instead of adding that code directly in oncreate().call your asyn task like this new FetchJsonTask().execute() in your oncreate. – Rachita Nanda Aug 01 '13 at 09:08
  • Thank you so much. I did what u teached. First I created FetchJsonTask class and copied the code u type, however, class FetchJsonTask extends AsyncTask { there is a error to third "void":Syntax error on token "void", Dimensions expected after this token then, JSONObject json = jParser.getJSONFromUrl(url); this code includes some error such as "local variable","add cast to jParser".. – user2640948 Aug 02 '13 at 01:39
  • then, super.onPostExecute(result); super.onPreExecute(); there exist some error finally, should I put "url" term in new FetchJsonTask().execute(); like new FetchJsonTask().execute(url); ?? thanks again! – user2640948 Aug 02 '13 at 01:39
  • and when i put new FetchJsonTask().execute(); under onCreate there is an error that method execute() is undefined. – user2640948 Aug 02 '13 at 01:50
1

you have called the Web from main thread. that's why you have got

Caused by: android.os.NetworkOnMainThreadException

after android 4.0 you cant do network operations on its UIThread. you need to use background threads. i will prefer to use AsyncTask for network call.

Hope it Helps!!

Armaan Stranger
  • 3,140
  • 1
  • 14
  • 24
1

read commented parts and change your code according to that.

class MyAsync extends AsyncTask<String, Void, Void> {

         @Override
         protected void onPreExecute() {
             super.onPreExecute();
         }

         @Override
         protected Void doInBackground(String... params) {
             // do your JSON parse here
             return null;
         }

         @Override
         protected void onPostExecute(Void result) {
             // after gettin json data do whatever you want here
             super.onPostExecute(result);
         }
    }

call your async class in your oncreate as:

new MyAsync().execute();
canova
  • 3,965
  • 2
  • 22
  • 39