简体   繁体   中英

How can I parse a JSON object and display it in a list view?

Below is the code I am having problems with. The php file works like a charm, as you can see if you go to the value the url_all_dates variable holds. Below this class is my .xml layout file for the list_item. The app runs but doesn't display any of the dates in the database.:

public class RequestTour extends ListActivity {

    // Progress Dialog
    private ProgressDialog pDialog;

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

    ArrayList<HashMap<String, String>> datesList;

    // url to get all dates list
    private static String url_all_dates = "http://www.prayingmantesconcepts.com/androidfinal/get_all_avail_dates.php";

    // JSON Node names
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_DATES = "dates";
    private static final String TAG_DATEID = "dateID";
    private static final String TAG_DATE = "date";

    // dates JSONArray
    JSONArray dates = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dates);//put dates layout here.

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

        // Loading dates in Background Thread
        new LoadAllDates().execute();

        // Get listview
        ListView lv = getListView();

        // on seleting single date
        // launching Book Tour Screen
        lv.setOnItemClickListener(new OnItemClickListener() {

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

                // Starting new intent
                Intent in = new Intent(getApplicationContext(),
                        BookTour.class);
                // sending dateID to next activity
                in.putExtra(TAG_DATEID, dateID);

                // starting new activity and expecting some response back
                startActivityForResult(in, 100);
            }
        });

    }

    // Response from Edit Product Activity
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // if result code 100
        if (resultCode == 100) {
            // if result code 100 is received 
            // means user booked a tour
            // reload this screen again
            Intent intent = getIntent();
            finish();
            startActivity(intent);
        }

    }

    /**
     * Background Async Task to Load all dates by making HTTP Request
     * */
    class LoadAllDates extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(RequestTour.this);
            pDialog.setMessage("Loading dates. Please wait...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }

        /**
         * getting All dates from url
         * */
        protected String doInBackground(String... args) {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            // getting JSON string from URL
            JSONObject json = jParser.makeHttpRequest(url_all_dates, "GET", params);

            // Check your log cat for JSON response
            Log.d("All Dates: ", json.toString());

            try {
                // Checking for SUCCESS TAG
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    //  found
                    // Getting Array of 
                     dates = json.getJSONArray(TAG_DATES);

                    // looping through All Dates Available for Request
                    for (int i = 0; i < dates.length(); i++) {
                        JSONObject c = dates.getJSONObject(i);

                        // Storing each json item in variable
                        String id = c.getString(TAG_DATEID);
                        String date = c.getString(TAG_DATE);

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

                        // adding each child node to HashMap key => value
                        map.put(TAG_DATEID, id);
                        map.put(TAG_DATE, date);

                        // adding HashList to ArrayList
                        datesList.add(map);
                    }
                } else {
                    // no  found
                    // Launch Add New product Activity
                    Intent i = new Intent(getApplicationContext(),
                            Main.class);
                    // Closing all previous activities
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(i);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
            // dismiss the dialog after getting all 
            pDialog.dismiss();
            // updating UI from Background Thread
            runOnUiThread(new Runnable() {
                public void run() {
                    /**
                     * Updating parsed JSON data into ListView
                     * */
                    ListAdapter adapter = new SimpleAdapter(
                            RequestTour.this, datesList,
                            R.layout.list_item, new String[] { TAG_DATEID,
                                    TAG_DATE},
                            new int[] { R.id.dateID, R.id.date });
                    // updating listview
                    setListAdapter(adapter);
                }
            });

        }

    }
}


<!------------------------------------------------------------------------------------>


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" >

    <!-- Date id (dateID) - will be HIDDEN - used to pass to other activity -->
    <TextView
        android:id="@+id/dateID"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:visibility="gone" />


    <!-- Date Label -->
    <TextView
        android:id="@+id/date"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="6dip"
        android:paddingLeft="6dip"
        android:textSize="17dip"
        android:textStyle="bold" />

</LinearLayout>

FIRST ISSUE : here

            // no  found
            // Launch Add New product Activity
            Intent i = new Intent(getApplicationContext(),
                    Main.class);
            // Closing all previous activities
            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);

you are trying to access Ui elements from background Thread .move these lines of code to onPostExecute for Updating UI from AsyncTask after doInBackground is completed.


SECOND ISSUE :

here

  protected void onPostExecute(String file_url) { // dismiss the dialog after getting all pDialog.dismiss(); // updating UI from Background Thread runOnUiThread(new Runnable() { public void run() { /** * Updating parsed JSON data into ListView * */ } }); 

because we are able to access UI elements in onPostExecute method of AsyncTask so no need to use runOnUiThread for updating UI elements in onPostExecute like in your case you are trying to use access ListAdapter or ListView inside runOnUiThread in onPostExecute


SOLUTION :

Change your LoadAllDates code as by using AsyncTask in proper way:

 class LoadAllDates extends AsyncTask<String, String, ArrayList<HashMap<String, String>>> { datesList=new ArrayList<HashMap<String, String>>; @Override protected void onPreExecute() { super.onPreExecute(); //YOUR CODE HERE } protected ArrayList<HashMap<String, String>> doInBackground(String... args) { // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); // getting JSON string from URL JSONObject json = jParser.makeHttpRequest(url_all_dates, "GET", params); // Check your log cat for JSON response Log.d("All Dates: ", json.toString()); try { // Checking for SUCCESS TAG int success = json.getInt(TAG_SUCCESS); if (success == 1) { // found // Getting Array of dates = json.getJSONArray(TAG_DATES); // looping through All Dates Available for Request for (int i = 0; i < dates.length(); i++) { JSONObject c = dates.getJSONObject(i); // Storing each json item in variable String id = c.getString(TAG_DATEID); String date = c.getString(TAG_DATE); // creating new HashMap HashMap<String, String> map = new HashMap<String, String>(); // adding each child node to HashMap key => value map.put(TAG_DATEID, id); map.put(TAG_DATE, date); // adding HashList to ArrayList datesList.add(map); } } else { // no found } } catch (JSONException e) { e.printStackTrace(); } return ArrayList<HashMap<String, String>>; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute( ArrayList<HashMap<String, String>> file_url) { // dismiss the dialog after getting all pDialog.dismiss(); // updating UI from Background Thread if(file_url.size()>0) { ListAdapter adapter = new SimpleAdapter( RequestTour.this, file_url, R.layout.list_item, new String[] { TAG_DATEID, TAG_DATE}, new int[] { R.id.dateID, R.id.date }); // updating listview setListAdapter(adapter); } else{ // Launch Add New product Activity Intent i = new Intent(getApplicationContext(), Main.class); // Closing all previous activities i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(i); } } } 
You have to use Gson Json parsing this is a good way to parse Json object

eg:

String json1 = "[{\"contactName\":\"3\",\"contactNumber\":\"3\"},{\"contactName\":\"4\",\"contactNumber\":\"4\"}]";

Gson gson = new Gson();
Type collectionType = new TypeToken<List<ContactDetail>>(){}.getType();
List<ContactDetail> details = gson.fromJson(json1, collectionType);

Here ContactDetail class consists of String contactName and String contactNumber and their corresponding getters and setters.
Note: make List<ContactDetail> details as a public static variable in your class and 
from your activity class pass this list object in your listview adapter.

here is my answer. Hope it helps. You can also visit the url i parsed: http://redsox.tcs.auckland.ac.nz/734A/CSService.svc/courses

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.zip.GZIPInputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ListActivity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class Courses extends Activity {

    ArrayList<String> items = new ArrayList<String>();

    //URL requestUrl = new URL(url);
    JSONArray courses = null;
    //private static final String TAG_COURSES = "Courses";
    static JSONObject jObj = null;
    static String json = "";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.courses);
        new MyTask().execute("http://redsox.tcs.auckland.ac.nz/734A/CSService.svc/courses");

    }


    private class MyTask extends AsyncTask<String, Void, JSONObject> {

        @Override
        protected JSONObject doInBackground(String... urls) {
           // return loadJSON(url);
            String url = new String(urls[0]);
            try {

                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                //HttpPost httpPost = new HttpPost(url);
                HttpGet httpGet = new HttpGet(url);
                HttpResponse httpResponse = httpClient.execute(httpGet);

                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, "UTF-8"), 8);*/
            InputStream inputStream = is;
            GZIPInputStream input = new GZIPInputStream(inputStream);
            InputStreamReader reader = new InputStreamReader(input);
            BufferedReader in = new BufferedReader(reader);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = in.readLine()) != null) {
                sb.append(line);
                //System.out.println(line);
            }
            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 {

            JSONArray courses = new JSONArray(json);
            //JSONArray people = new JSONArray(json);
            for (int i = 0; i < courses.length(); i++) {
                //System.out.println(courses.getJSONObject(i).toString());
                JSONObject c = courses.getJSONObject(i);

                // Storing each json item in variable
                String course_id = c.getString("codeField");
                String course_name = c.getString("titleField");
                String course_semester = c.getString("semesterField");

                items.add(course_id +"\n"+course_name+"\t"+course_semester);

                /*Log.v("--", "Course:" + course_id + "\n Course Title: " + course_name
                        + "\n Semesters offered: " + course_semester);*/
            }


            //jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        } 


        // return JSON String
        return jObj;
        }

        @SuppressWarnings("unchecked")
        protected void onPostExecute(JSONObject json) {
            ListView myListView = (ListView)findViewById(R.id.coursesList);
            myListView.setAdapter(new ArrayAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, items));

    }
    }




}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM