3

I have created 2 java based apps for android which are both working independantly.

The first, a simple app with a few text field and boxes with onClick features to switch between pages,

the second a JSON list (yes thats all thats in the app)

I am trying to put the JSON list app in the middle of the 1st app, but when I click on the onClick button aimed at my JSON.java page, it crashes out, but when I run the JSON.java page from its own app, it runs fine.

Sorry to everyone for me dumping loads of code into this, but I am new to android, and don't know to much about it, so not sure which parts are/are not relevant.

HomePage.Java

package com.example.assent.app;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;

public class HomePage extends Activity {

public void SelectClient(View view) 
{
    Intent intent = new Intent(HomePage.this, AndroidJSONParsingActivity.class);
    startActivity(intent);
}

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_home_page, menu);
    return true;
}
}

LAYOUT - activity_home_page.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top"
android:orientation="vertical" >

<TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    android:layout_gravity="center_horizontal"
    android:layout_weight="0.08"
    android:text="@string/Home_Text1"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="@string/Home_Text2"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<EditText
    android:id="@+id/editText3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textPersonName" />

<TableLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="0.06" >

    <TableRow
        android:id="@+id/tableRow1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </TableRow>

    <TableRow
        android:id="@+id/tableRow2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </TableRow>

    <TableRow
        android:id="@+id/tableRow3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </TableRow>

    <TableRow
        android:id="@+id/tableRow4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </TableRow>
</TableLayout>

<TextView
    android:id="@+id/textView4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="@string/Home_Text3"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
    android:id="@+id/textView5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="@string/Home_Text4"
    android:textAppearance="?android:attr/textAppearanceSmall" />

<EditText
    android:id="@+id/editText2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textPassword" />

<TableLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="0.09" >

    <TableRow
        android:id="@+id/TableRow02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </TableRow>

    <TableRow
        android:id="@+id/TableRow01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </TableRow>

    <TableRow
        android:id="@+id/TableRow04"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </TableRow>

    <TableRow
        android:id="@+id/TableRow03"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </TableRow>
</TableLayout>

<Button
    android:id="@+id/button1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="SelectClient"
    android:text="@string/Home_Button1" />

</LinearLayout>

MENU - activity_home_page.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_settings"
    android:title="@string/menu_settings"
    android:orderInCategory="100"
    android:showAsAction="never" />
</menu>

JSON JAVA - AndroidJSONParsingActivity.java

package com.example.assent.app;

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 AndroidJSONParsingActivity extends ListActivity {

// url to make request
private static String url = "http://dcc.assentbc.co.uk/GetClients.aspx?SecureID=*******";

// JSON Node names
private static final String TAG_CONTACTS = "Clients";
private static final String TAG_NAME = "CompanyName";

// contacts JSONArray
JSONArray Clients = 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
        Clients = json.getJSONArray(TAG_CONTACTS);

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

            // Storing each json item in variable
            String name = c.getString(TAG_NAME);

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

            // adding each child node to HashMap key => value
            map.put(TAG_NAME, name);

            // 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 }, new int[] {
                    R.id.name });

    setListAdapter(adapter);

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

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

        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();

            // Starting new intent
            Intent in = new Intent(getApplicationContext(),     SingleMenuItemActivity.class);
            in.putExtra(TAG_NAME, name);
            startActivity(in);
        }
    });
}

}

JSON PARSER JAVA - JSONParser.java

package com.example.assent.app;

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;

}
}

JSON ITEM - SingleMenuItemActivity.java

package com.example.assent.app;

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 = "CompanyName";
@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);

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

    lblName.setText(name);
}
}

LAYOUT LIST ITEM - list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <!-- Name Label -->
    <TextView
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="#43bd00"
        android:textSize="16sp"
        android:textStyle="bold"
        android:paddingTop="6dip"
        android:paddingBottom="2dip" />

    </LinearLayout>

MAIN LAYOUT - main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!-- Main ListView 
     Always give id value as list(@android:id/list)
-->
<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"/>

</LinearLayout>

SINGLE ITEM LAYOUT - single_item_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Name Label -->
<TextView android:id="@+id/name_label"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="25dip"
        android:textStyle="bold"
        android:paddingTop="10dip"
        android:paddingBottom="10dip"
        android:textColor="#43bd00"/>
<!-- Description Label -->
<TextView android:id="@+id/email_label"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="#acacac"/>
<!-- Price Label -->
<TextView android:id="@+id/mobile_label"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"/>
</LinearLayout>

MY MANIFEST

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.assent.app"
android:versionCode="1"
android:versionName="1.0" >

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

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <activity
        android:name=".HomePage"
        android:label="@string/title_activity_home_page" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.HomePage" />
    </activity>
    <activity
        android:name=".Photos"
        android:label="@string/title_activity_photos" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.MainActivity" />
    </activity>
    <activity
        android:name=".AudioNotes"
        android:label="@string/title_activity_audio_notes" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.MainActivity" />
    </activity>
    <activity
        android:name=".Notes"
        android:label="@string/title_activity_notes" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.MainActivity" />
    </activity>
    <activity
        android:name=".Documents"
        android:label="@string/title_activity_documents" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.MainActivity" />
    </activity>
    <activity
        android:name=".PhotosSuccess"
        android:label="@string/title_activity_photos_success" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.MainActivity" />
    </activity>
    <activity
        android:name=".PhotosActivity"
        android:label="@string/title_activity_photos" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.MainActivity" />
    </activity>
    <activity
        android:name=".Photos_Upload"
        android:label="@string/title_activity_photos__upload" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.MainActivity" />
    </activity>
    <activity
        android:name=".ImageUpload"
        android:label="@string/title_activity_image_upload" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.MainActivity" />
    </activity>
    <activity
        android:name=".Notes_Upload"
        android:label="@string/title_activity_notes__upload" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.MainActivity" />
    </activity>
    <activity
        android:name=".SelectClient"
        android:label="@string/title_activity_select_client" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.assent.app.HomePage" />
    </activity>
    <activity
        android:label="@string/app_name"
        android:name=".AndroidJSONParsingActivity" >
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <!-- Single List Item View -->
    <activity
        android:label="Single Menu Item"
        android:name=".SingleMenuItemActivity" >
    </activity>
</application>

<uses-permission android:name="android.permission.INTERNET" />
</manifest>

MY ECLIPSE LOG

11-22 12:10:56.638: D/dalvikvm(381): GC_FOR_ALLOC freed 88K, 3% free 6478K/6663K, paused 56ms
11-22 12:10:56.648: I/dalvikvm-heap(381): Grow heap (frag case) to 6.872MB for 513744-byte allocation
11-22 12:10:56.738: D/dalvikvm(381): GC_FOR_ALLOC freed 2K, 3% free 6977K/7175K, paused 53ms
11-22 12:10:56.868: D/dalvikvm(381): GC_CONCURRENT freed <1K, 3% free 6977K/7175K, paused 4ms+22ms
11-22 12:10:56.938: D/AndroidRuntime(381): Shutting down VM
11-22 12:10:56.938: W/dalvikvm(381): threadid=1: thread exiting with uncaught exception (group=0x40014760)
11-22 12:10:56.958: E/AndroidRuntime(381): FATAL EXCEPTION: main
11-22 12:10:56.958: E/AndroidRuntime(381): java.lang.RuntimeException: Unable to start activity          ComponentInfo{com.example.assent.app/com.example.assent.app.AndroidJSONParsingActivity}: android.os.NetworkOnMainThreadException
11-22 12:10:56.958: E/AndroidRuntime(381):  at     android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
11-22 12:10:56.958: E/AndroidRuntime(381):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
11-22 12:10:56.958: E/AndroidRuntime(381):  at android.app.ActivityThread.access$500(ActivityThread.java:122)
11-22 12:10:56.958: E/AndroidRuntime(381):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
11-22 12:10:56.958: E/AndroidRuntime(381):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-22 12:10:56.958: E/AndroidRuntime(381):  at android.os.Looper.loop(Looper.java:132)
11-22 12:10:56.958: E/AndroidRuntime(381):  at     android.app.ActivityThread.main(ActivityThread.java:4123)
11-22 12:10:56.958: E/AndroidRuntime(381):  at java.lang.reflect.Method.invokeNative(Native Method)
11-22 12:10:56.958: E/AndroidRuntime(381):  at java.lang.reflect.Method.invoke(Method.java:491)
11-22 12:10:56.958: E/AndroidRuntime(381):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
11-22 12:10:56.958: E/AndroidRuntime(381):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
11-22 12:10:56.958: E/AndroidRuntime(381):  at dalvik.system.NativeStart.main(Native Method)
11-22 12:10:56.958: E/AndroidRuntime(381): Caused by: android.os.NetworkOnMainThreadException
11-22 12:10:56.958: E/AndroidRuntime(381):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1077)
11-22 12:10:56.958: E/AndroidRuntime(381):  at java.net.InetAddress.lookupHostByName(InetAddress.java:477)
11-22 12:10:56.958: E/AndroidRuntime(381):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:277)
11-22 12:10:56.958: E/AndroidRuntime(381):  at java.net.InetAddress.getAllByName(InetAddress.java:249)
11-22 12:10:56.958: E/AndroidRuntime(381):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:136)
11-22 12:10:56.958: E/AndroidRuntime(381):  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
11-22 12:10:56.958: E/AndroidRuntime(381):  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
11-22 12:10:56.958: E/AndroidRuntime(381):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
11-22 12:10:56.958: E/AndroidRuntime(381):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
11-22 12:10:56.958: E/AndroidRuntime(381):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
11-22 12:10:56.958: E/AndroidRuntime(381):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
11-22 12:10:56.958: E/AndroidRuntime(381):  at com.example.assent.app.JSONParser.getJSONFromUrl(JSONParser.java:38)
11-22 12:10:56.958: E/AndroidRuntime(381):  at com.example.assent.app.AndroidJSONParsingActivity.onCreate(AndroidJSONParsingActivity.java:46)
11-22 12:10:56.958: E/AndroidRuntime(381):  at android.app.Activity.performCreate(Activity.java:4397)
11-22 12:10:56.958: E/AndroidRuntime(381):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
11-22 12:10:56.958: E/AndroidRuntime(381):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
11-22 12:10:56.958: E/AndroidRuntime(381):  ... 11 more
11-22 12:11:00.760: I/Process(381): Sending signal. PID: 381 SIG: 9

Sorry once again for code dumping, hopefully somebody can point me in the right direction

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Henry Aspden
  • 382
  • 2
  • 5
  • 15

2 Answers2

2

It is recommended to use AsyncTask for network operations. Prior to Honey Comb it won't give any error but from HoneyComb version network operations on Main UI thread will result in NetworkOnUIthread exception.

So Call your : JSONObject json = jParser.getJSONFromUrl(url); to doInBackGround() method of async task and update your UI with the results in OnPostExecute Method.

chinna
  • 56
  • 4
1

From your logcat

11-22 12:10:56.958: E/AndroidRuntime(381): java.lang.RuntimeException: Unable to start activity          ComponentInfo{com.example.assent.app/com.example.assent.app.AndroidJSONParsingActivity}: android.os.NetworkOnMainThreadException

You are downloading your json on the main thread, wich throws and exception on Android 3.0+.

The specific line is this : JSONObject json = jParser.getJSONFromUrl(url);. Move it to another thread and it should fix your problem.

Consider using an AsyncTask, or check other options here

Marcelo
  • 1,471
  • 3
  • 19
  • 22
  • Your main thread should be responsible for updating the user interface only, not performing downloads and parsing json/xml files. Consider using an `AsyncTask` for that. More info on this problem here: http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html – Marcelo Nov 22 '12 at 12:43
  • thanks for your help... Now I just have to figure out exactly what this all means for my project :D Thanks Henry – Henry Aspden Nov 22 '12 at 12:44
  • See if this helps: http://stackoverflow.com/questions/9353700/setting-up-async-task-for-loading-json-into-a-listview – Marcelo Nov 22 '12 at 12:45