Ty Jacobs
Ty Jacobs

Reputation: 113

Load JSON response to Listview with Button OnClickListener

I am a VB'er (VB Developer). I decided to give Android/Java a go. Well, so far it hasn't been going so good. I seem to run in circles with Android. I bought some books, did some tutorials, etc. Still, I always find myself in a loop of confusion when it comes to Android. I have been attempting to manually assign a string a value and then press a button and send that value "pid" to a php script, have it retrieve the response and populate a ListView. I can get it to work by creating a php script for every pid but I was trying to create one script, send the value and retrieve everything that matched in a test DB. FYI, I am also not very familiar with PHP but it seems pretty easy.

HERE IS MY MAINACTIVITY:

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

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {
     String pid; 

        // Progress Dialog 
        private ProgressDialog MyDialog; 

        // JSON parser class 
        JSONParser jsonParser = new JSONParser(); 

        // Product URL
        private static final String url_product_detials = "http://xxx.xxx.xxx.xxx/phpTest.php"; 

        // JSON Node names 
        private static final String TAG_SUCCESS = "success"; 
        private static final String TAG_PRODUCT = "product"; 
        private static final String TAG_PID = "pid"; 
        private static final String TAG_NAME = "name"; 
        private static final String TAG_PRICE = "price"; 
        private static final String TAG_DESCRIPTION = "description";
        JSONArray products = null;
        ArrayList<HashMap<String, String>> getSpecificList;
        ListView list;
        Button MyButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Assign pid generic value from test DB.
           pid = "dfdf";
           list = (ListView)findViewById(R.id.listView1);
           MyButton = (Button)findViewById(R.id.button1);

           MyButton.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                new GetProductDetails().execute();
            }

           });
    }
     class GetProductDetails extends AsyncTask<String, String, String> { 

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

            /** 
             * Getting product details in background thread 
             * */
            protected String doInBackground(String... params) { 

                // updating UI from Background Thread 
                runOnUiThread(new Runnable() { 
                    public void run() { 
                        // Check for success tag 
                        int success; 
                        try { 
                            // Building Parameters 
                            List<NameValuePair> params = new ArrayList<NameValuePair>(); 
                            params.add(new BasicNameValuePair("pid", pid)); 

                            // getting product details by making HTTP request 
                            // Note that product details url will use GET request 
                            JSONObject json = jsonParser.makeHttpRequest(url_product_detials, "GET", params); 

                            // check your log for json response 
                            Log.d("Single Product Details", json.toString()); 

                            // json success tag 
                            success = json.getInt(TAG_SUCCESS); 
                            if (success == 1) { 
                                // successfully received product details 
                                products = json.getJSONArray(TAG_PRODUCT); 

                                for (int i = 0; i < products.length(); i++) {
                                    JSONObject c = products.getJSONObject(i);

                                    // Storing JSON Items
                                    String id = c.getString(TAG_PID);
                            String name = c.getString(TAG_NAME);
                                    String updated_at = c.getString(TAG_PRICE);

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

                                    // adding each child node to HashMap key => value
                                    map.put(TAG_PID, id);
                                    map.put(TAG_NAME, name);
                                    map.put(TAG_PRICE, updated_at);
                                    // adding HashList to ArrayList
                                    getSpecificList.add(map);
                                }


                            }else{ 
                                // product with pid not found 
                            } 
                        } catch (JSONException e) { 
                            e.printStackTrace(); 
                        } 
                    } 
                }); 

                return null; 
            } 

            /** 
             * After completing background task Dismiss the progress dialog 
             * **/
            protected void onPostExecute(String file_url) { 
                // dismiss dialog 
                MyDialog.dismiss();
                // updating UI from Background Thread
                runOnUiThread(new Runnable() {
                    public void run() {

                ListAdapter adapter = new SimpleAdapter(MainActivity.this, getSpecificList,R.layout.list_item, new String[] { TAG_PID,TAG_NAME},new int[] { R.id.pid, R.id.name2 });
                list.setAdapter(adapter);
                    }

                });
            }
        }

    @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;
    }

}

Below is the PHP

<?php 

// array for JSON response 
$response = array(); 

// include db connect class 
require_once __DIR__ . '/db_connect.php'; 

// connecting to db 
$db = new DB_CONNECT(); 

// check for post data 
if (isset($_GET["pid"])) { 
    $pid = $_GET['pid']; 

    // get and item from the table products in the column PRICE that is equal to pid
    $result = mysql_query("SELECT *FROM products WHERE price LIKE $pid"); 

    if (!empty($result)) { 
        // check to see if there is a result
        if (mysql_num_rows($result) > 0) { 

            $result = mysql_fetch_array($result); 

            $product = array(); 
            $product["pid"] = $result["pid"]; 
            $product["name"] = $result["name"]; 
            $product["price"] = $result["price"]; 
            $product["description"] = $result["description"]; 
            $product["created_at"] = $result["created_at"]; 
            $product["updated_at"] = $result["updated_at"]; 
            // success 
            $response["success"] = 1; 

            // user node 
            $response["product"] = array(); 

            array_push($response["product"], $product); 

            // echoing JSON response 
            echo json_encode($response); 
        } else { 
            // no product found 
            $response["success"] = 0; 
            $response["message"] = "No product found"; 

            // echo no users JSON 
            echo json_encode($response); 
        } 
    } else { 
        // no product found 
        $response["success"] = 0; 
        $response["message"] = "No product found"; 

        // echo no users JSON 
        echo json_encode($response); 
    } 
} else { 
    // required field is missing 
    $response["success"] = 0; 
    $response["message"] = "Required field(s) is missing"; 

    // echoing JSON response 
    echo json_encode($response); 
} 
?>

Here is the LogCat Output:

06-18 08:03:36.415: W/dalvikvm(19438): threadid=1: thread exiting with uncaught exception (group=0x41e422a0)
06-18 08:03:36.415: E/AndroidRuntime(19438): FATAL EXCEPTION: main
06-18 08:03:36.415: E/AndroidRuntime(19438): android.os.NetworkOnMainThreadException
06-18 08:03:36.415: E/AndroidRuntime(19438):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at libcore.io.IoBridge.connect(IoBridge.java:112)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at java.net.Socket.connect(Socket.java:842)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at com.example.php_sql_listview.JSONParser.makeHttpRequest(JSONParser.java:62)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at com.example.php_sql_listview.MainActivity$GetProductDetails$1.run(MainActivity.java:99)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at android.os.Handler.handleCallback(Handler.java:615)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at android.os.Handler.dispatchMessage(Handler.java:92)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at android.os.Looper.loop(Looper.java:137)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at android.app.ActivityThread.main(ActivityThread.java:4898)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at java.lang.reflect.Method.invokeNative(Native Method)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at java.lang.reflect.Method.invoke(Method.java:511)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
06-18 08:03:36.415: E/AndroidRuntime(19438):    at dalvik.system.NativeStart.main(Native Method)

I did notice the Fatal Thread error so I tried removing the below but I got the same error.

runOnUiThread(new Runnable() {
public void run() {

Thanks for your help. I do appreciate it. I try for a week or two before I bother you guys with something that may be simple. I have 7 books on Java and Android Dev. but not a single one talks about GSON, JSON, or really anything other than small notes on SQLite. Anyways, thanks again.

LogCat Output after suggestions:

06-18 09:07:09.160: E/AndroidRuntime(26519): FATAL EXCEPTION: main
06-18 09:07:09.160: E/AndroidRuntime(26519): android.os.NetworkOnMainThreadException
06-18 09:07:09.160: E/AndroidRuntime(26519):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at libcore.io.IoBridge.connect(IoBridge.java:112)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at java.net.Socket.connect(Socket.java:842)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at com.example.php_sql_listview.JSONParser.makeHttpRequest(JSONParser.java:62)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at com.example.php_sql_listview.MainActivity$GetProductDetails$1.run(MainActivity.java:99)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at android.os.Handler.handleCallback(Handler.java:615)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at android.os.Handler.dispatchMessage(Handler.java:92)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at android.os.Looper.loop(Looper.java:137)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at android.app.ActivityThread.main(ActivityThread.java:4898)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at java.lang.reflect.Method.invokeNative(Native Method)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at java.lang.reflect.Method.invoke(Method.java:511)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
06-18 09:07:09.160: E/AndroidRuntime(26519):    at dalvik.system.NativeStart.main(Native Method)

I had already tried removing what has been suggested. See above. Thanks.

Changes to Code:

 class GetProductDetails extends AsyncTask<String, String, String> { 

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

            /** 
             * Getting product details in background thread 
             * */
            protected String doInBackground(String... args) { 

                // updating UI from Background Thread 
                List<NameValuePair> params = new ArrayList<NameValuePair>(); 
                params.add(new BasicNameValuePair("pid", pid)); 
                JSONObject json = jsonParser.makeHttpRequest(url_product_detials, "GET", params); 
                // check your log for json response 
                Log.d("Single Product Details", json.toString()); 

                        // Check for success tag 

                        try { 

                            // json success tag 
                             int success = json.getInt(TAG_SUCCESS); 
                            if (success == 1) { 
                                // successfully received product details 
                                products = json.getJSONArray(TAG_PRODUCT); 

                                for (int i = 0; i < products.length(); i++) {
                                    JSONObject c = products.getJSONObject(i);

                                    // Storing JSON Items
                                    String id = c.getString(TAG_PID);
                            String name = c.getString(TAG_NAME);
                                    String updated_at = c.getString(TAG_PRICE);

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

                                    // adding each child node to HashMap key => value
                                    map.put(TAG_PID, id);
                                    map.put(TAG_NAME, name);
                                    map.put(TAG_PRICE, updated_at);
                                    // adding HashList to ArrayList
                                    getSpecificList.add(map);
                                }


                            }else{ 
                                // product with pid not found 
                            } 
                        } catch (JSONException e) { 
                            e.printStackTrace(); 
                        } 



                return null; 
            } 

            /** 
             * After completing background task Dismiss the progress dialog 
             * **/
            protected void onPostExecute(String file_url) { 
                // dismiss dialog 
                MyDialog.dismiss();

                ListAdapter adapter = new SimpleAdapter(MainActivity.this, getSpecificList,R.layout.list_item, new String[] { TAG_PID,TAG_NAME},new int[] { R.id.pid, R.id.name2 });
                list.setAdapter(adapter);
                    }
        }

Still getting a Thread Exception: LogCat 6/19/2013:

06-19 15:11:04.599: D/Single Product Details(27108): {"product":[{"created_at":"svsvsvsv","pid":"dfdf","updated_at":"http:\/\/xxx.xxx.xxx.xxx\/img\/8Cell.jpg","price":"MYPRICE","description":"","name":"dfdf"}],"success":1}
06-19 15:11:04.604: W/System.err(27108): org.json.JSONException: No value for products
06-19 15:11:04.604: W/System.err(27108):    at org.json.JSONObject.get(JSONObject.java:354)
06-19 15:11:04.604: W/System.err(27108):    at org.json.JSONObject.getJSONArray(JSONObject.java:544)
06-19 15:11:04.604: W/System.err(27108):    at com.example.php_sql_listview.MainActivity$LoadAllProducts.doInBackground(MainActivity.java:105)
06-19 15:11:04.604: W/System.err(27108):    at com.example.php_sql_listview.MainActivity$LoadAllProducts.doInBackground(MainActivity.java:1)
06-19 15:11:04.604: W/System.err(27108):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
06-19 15:11:04.604: W/System.err(27108):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
06-19 15:11:04.604: W/System.err(27108):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-19 15:11:04.604: W/System.err(27108):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-19 15:11:04.604: W/System.err(27108):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-19 15:11:04.604: W/System.err(27108):    at java.lang.Thread.run(Thread.java:856)
06-19 15:11:04.609: D/AndroidRuntime(27108): Shutting down VM
06-19 15:11:04.609: W/dalvikvm(27108): threadid=1: thread exiting with uncaught exception (group=0x41e422a0)
06-19 15:11:04.619: D/dalvikvm(27108): GC_CONCURRENT freed 192K, 6% free 12401K/13127K, paused 12ms+12ms, total 41ms
06-19 15:11:04.624: E/AndroidRuntime(27108): FATAL EXCEPTION: main
06-19 15:11:04.624: E/AndroidRuntime(27108): java.lang.NullPointerException
06-19 15:11:04.624: E/AndroidRuntime(27108):    at android.widget.SimpleAdapter.getCount(SimpleAdapter.java:93)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at android.widget.ListView.setAdapter(ListView.java:466)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at com.example.php_sql_listview.MainActivity$LoadAllProducts.onPostExecute(MainActivity.java:147)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at com.example.php_sql_listview.MainActivity$LoadAllProducts.onPostExecute(MainActivity.java:1)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at android.os.AsyncTask.finish(AsyncTask.java:631)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at android.os.Handler.dispatchMessage(Handler.java:99)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at android.os.Looper.loop(Looper.java:137)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at android.app.ActivityThread.main(ActivityThread.java:4898)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at java.lang.reflect.Method.invokeNative(Native Method)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at java.lang.reflect.Method.invoke(Method.java:511)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
06-19 15:11:04.624: E/AndroidRuntime(27108):    at dalvik.system.NativeStart.main(Native Method)

Upvotes: 0

Views: 598

Answers (3)

FrancescoAzzola
FrancescoAzzola

Reputation: 2654

The problem is that you are trying to use an HTTP connection in your Main Thread. This could cause a ANR problem. You have wisely used AsyncTask but the way you used it isn't correct. First of all doInBackgorund is used to do the "heavy" task in a way that the main thread isn't stopped. But if you runOnUIThread the heavy process then you are invalidating the use of AsyncTask. In onPostExecute method you should update the ui. In this case runOnUIThread is useless beacause it runs already in the main thread. So 1. Remove runOnUIThread in doInBackground 2. Remove runOnUIThread in onPostExecute

Upvotes: 2

Sagar Maiyad
Sagar Maiyad

Reputation: 12743

Remove Below code from onPostExecute Method:

runOnUiThread(new Runnable() {
                    public void run() {
                      }
                }

and put your listview adapters line:

ListAdapter adapter = new SimpleAdapter(MainActivity.this, getSpecificList,R.layout.list_item, new String[] { TAG_PID,TAG_NAME},new int[] { R.id.pid, R.id.name2 });
list.setAdapter(adapter);

as it is.

Upvotes: 0

CRUSADER
CRUSADER

Reputation: 5472

This exception is thrown when an application attempts to perform a networking operation on its main thread. Run your code in AsyncTask..... in your code runOnUiThread in post execute is where the problem is...

Upvotes: 0

Related Questions