I’m developing a test Android application that must display some data from a mysql db. Here my logs:
05-22 17:10:56.865: E/JSON Parser(31648): Error parsing data org.json.JSONException: End of input at character 0 of 05-22 17:10:56.865: W/dalvikvm(31648): threadid=11: thread exiting with uncaught exception (group=0x418e3da0) 05-22 17:10:56.875: E/AndroidRuntime(31648): FATAL EXCEPTION: AsyncTask #1 05-22 17:10:56.875: E/AndroidRuntime(31648): Process: com.example.androidhive, PID: 31648 05-22 17:10:56.875: E/AndroidRuntime(31648): java.lang.RuntimeException: An error occured while executing doInBackground() 05-22 17:10:56.875: E/AndroidRuntime(31648): at android.os.AsyncTask$3.done(AsyncTask.java:300) 05-22 17:10:56.875: E/AndroidRuntime(31648): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) 05-22 17:10:56.875: E/AndroidRuntime(31648): at java.util.concurrent.FutureTask.setException(FutureTask.java:222) 05-22 17:10:56.875: E/AndroidRuntime(31648): at java.util.concurrent.FutureTask.run(FutureTask.java:242) 05-22 17:10:56.875: E/AndroidRuntime(31648): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 05-22 17:10:56.875: E/AndroidRuntime(31648): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 05-22 17:10:56.875: E/AndroidRuntime(31648): at java.lang.Thread.run(Thread.java:841) 05-22 17:10:56.875: E/AndroidRuntime(31648): Caused by: java.lang.NullPointerException 05-22 17:10:56.875: E/AndroidRuntime(31648): at com.example.androidhive.AllProductsActivity$LoadAllProducts.doInBackground(AllProductsActivity.java:130) 05-22 17:10:56.875: E/AndroidRuntime(31648): at com.example.androidhive.AllProductsActivity$LoadAllProducts.doInBackground(AllProductsActivity.java:1) 05-22 17:10:56.875: E/AndroidRuntime(31648): at android.os.AsyncTask$2.call(AsyncTask.java:288) 05-22 17:10:56.875: E/AndroidRuntime(31648): at java.util.concurrent.FutureTask.run(FutureTask.java:237) 05-22 17:10:56.875: E/AndroidRuntime(31648): ... 3 more 05-22 17:10:57.436: D/AbsListView(31648): onDetachedFromWindow 05-22 17:10:57.436: D/AbsListView(31648): unregisterIRListener() is called 05-22 17:10:57.446: E/WindowManager(31648): android.view.WindowLeaked: Activity com.example.androidhive.AllProductsActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{42c02238 V.E..... R.....ID 0,0-914,346} that was originally added here 05-22 17:10:57.446: E/WindowManager(31648): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:456) 05-22 17:10:57.446: E/WindowManager(31648): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:267) 05-22 17:10:57.446: E/WindowManager(31648): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) 05-22 17:10:57.446: E/WindowManager(31648): at android.app.Dialog.show(Dialog.java:288) 05-22 17:10:57.446: E/WindowManager(31648): at com.example.androidhive.AllProductsActivity$LoadAllProducts.onPreExecute(AllProductsActivity.java:117) 05-22 17:10:57.446: E/WindowManager(31648): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:587) 05-22 17:10:57.446: E/WindowManager(31648): at android.os.AsyncTask.execute(AsyncTask.java:535) 05-22 17:10:57.446: E/WindowManager(31648): at com.example.androidhive.AllProductsActivity.onCreate(AllProductsActivity.java:57) 05-22 17:10:57.446: E/WindowManager(31648): at android.app.Activity.performCreate(Activity.java:5426) 05-22 17:10:57.446: E/WindowManager(31648): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105) 05-22 17:10:57.446: E/WindowManager(31648): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269) 05-22 17:10:57.446: E/WindowManager(31648): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363) 05-22 17:10:57.446: E/WindowManager(31648): at android.app.ActivityThread.access$900(ActivityThread.java:161) 05-22 17:10:57.446: E/WindowManager(31648): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265) 05-22 17:10:57.446: E/WindowManager(31648): at android.os.Handler.dispatchMessage(Handler.java:102) 05-22 17:10:57.446: E/WindowManager(31648): at android.os.Looper.loop(Looper.java:157) 05-22 17:10:57.446: E/WindowManager(31648): at android.app.ActivityThread.main(ActivityThread.java:5356) 05-22 17:10:57.446: E/WindowManager(31648): at java.lang.reflect.Method.invokeNative(Native Method) 05-22 17:10:57.446: E/WindowManager(31648): at java.lang.reflect.Method.invoke(Method.java:515) 05-22 17:10:57.446: E/WindowManager(31648): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265) 05-22 17:10:57.446: E/WindowManager(31648): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081) 05-22 17:10:57.446: E/WindowManager(31648): at dalvik.system.NativeStart.main(Native Method) 05-22 17:11:01.279: I/Process(31648): Sending signal. PID: 31648 SIG: 9
Here the class JSONParser.java
package com.example.androidhive; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URLEncodedUtils; 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() { } // function get json from url // by making HTTP POST or GET mehtod public JSONObject makeHttpRequest(String url, String method, List<NameValuePair> params) { // Making HTTP request try { // check for request method if(method == "POST"){ // request method is POST // defaultHttpClient DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new UrlEncodedFormEntity(params)); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); }else if(method == "GET"){ // request method is GET DefaultHttpClient httpClient = new DefaultHttpClient(); String paramString = URLEncodedUtils.format(params, "utf-8"); url += "?" + paramString; HttpGet httpGet = new HttpGet(url); HttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); }
Here the class I use to display the selected data:
package com.example.androidhive; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.apache.http.NameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.ListActivity; import android.app.ProgressDialog; import android.content.Intent; import android.os.AsyncTask; 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 AllProductsActivity extends ListActivity { // Progress Dialog private ProgressDialog pDialog; // Creating JSON Parser object JSONParser jParser = new JSONParser(); ArrayList<HashMap<String, String>> productsList; // url to get all products list private static String url_all_products = "http://10.1.20.10/android/get_all_products.php"; // JSON Node names private static final String TAG_SUCCESS = "success"; private static final String TAG_PRODUCTS = "products"; private static final String TAG_PID = "pid"; private static final String TAG_NAME = "name"; // products JSONArray JSONArray products = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.all_products); // Hashmap for ListView productsList = new ArrayList<HashMap<String, String>>(); // Loading products in Background Thread new LoadAllProducts().execute(); // Get listview ListView lv = getListView(); // on seleting single product // launching Edit Product Screen lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // getting values from selected ListItem String pid = ((TextView) view.findViewById(R.id.pid)).getText() .toString(); // Starting new intent Intent in = new Intent(getApplicationContext(), EditProductActivity.class); // sending pid to next activity in.putExtra(TAG_PID, pid); // 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 edited/deleted product // reload this screen again Intent intent = getIntent(); finish(); startActivity(intent); } } /** * Background Async Task to Load all product by making HTTP Request * */ class LoadAllProducts extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(AllProductsActivity.this); pDialog.setMessage("Loading products. Please wait..."); pDialog.setIndeterminate(false); pDialog.setCancelable(false); pDialog.show(); } /** * getting All products 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_products, "GET", params); // Check your log cat for JSON reponse Log.d("All Products: ", json.toString()); try { // Checking for SUCCESS TAG int success = json.getInt(TAG_SUCCESS); if (success == 1) { // products found // Getting Array of Products products = json.getJSONArray(TAG_PRODUCTS); // looping through All Products for (int i = 0; i < products.length(); i++) { JSONObject c = products.getJSONObject(i); // Storing each json item in variable String id = c.getString(TAG_PID); 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_PID, id); map.put(TAG_NAME, name); // adding HashList to ArrayList productsList.add(map); } } else { // no products found // Launch Add New product Activity Intent i = new Intent(getApplicationContext(), NewProductActivity.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 products pDialog.dismiss(); // updating UI from Background Thread runOnUiThread(new Runnable() { public void run() { /** * Updating parsed JSON data into ListView * */ ListAdapter adapter = new SimpleAdapter( AllProductsActivity.this, productsList, R.layout.list_item, new String[] { TAG_PID, TAG_NAME}, new int[] { R.id.pid, R.id.name }); // updating listview setListAdapter(adapter); } }); } } }
Here the php file:
get_all_products.php <?php /* * Following code will list all the products */ // array for JSON response $response = array(); // include db connect class require_once __DIR__ . '/db_connect.php'; // connecting to db $db = new DB_CONNECT(); // get all products from products table $result = mysql_query("SELECT *FROM products") or die(mysql_error()); // check for empty result if (mysql_num_rows($result) > 0) { // looping through all results // products node $response["products"] = array(); while ($row = mysql_fetch_array($result)) { // temp user array $product = array(); $product["pid"] = $row["pid"]; $product["name"] = $row["name"]; $product["price"] = $row["price"]; $product["created_at"] = $row["created_at"]; $product["updated_at"] = $row["updated_at"]; // push single product into final response array array_push($response["products"], $product); } // success $response["success"] = 1; // echoing JSON response echo json_encode($response); } else { // no products found $response["success"] = 0; $response["message"] = "No products found"; // echo no users JSON echo json_encode($response); } ?>
In addition, here the main Activity:
package com.example.androidhive; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainScreenActivity extends Activity{ Button btnViewProducts; Button btnNewProduct; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_screen); // Buttons btnViewProducts = (Button) findViewById(R.id.btnViewProducts); btnNewProduct = (Button) findViewById(R.id.btnCreateProduct); // view products click event btnViewProducts.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Launching All products Activity Intent i = new Intent(getApplicationContext(), AllProductsActivity.class); startActivity(i); } }); // view products click event btnNewProduct.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Launching create new product activity Intent i = new Intent(getApplicationContext(), NewProductActivity.class); startActivity(i); } }); } }
I read various thread around the internet about this error, but it is even caused by differents problems, and I did not found a case similar to mine or a solution that solved my problem.
Advertisement
Answer
Looks like your PHP file is returning invalid response.
If you are writing a handler which returns JSON, it should return valid JSON response ANYWAY.
Here is how it should be:
$response = array(); $response["success"] = 0; $response["message"] = "No products found"; // include db connect class require_once __DIR__ . '/db_connect.php'; // connecting to db $db = new DB_CONNECT(); // get all products from products table $result = mysql_query("SELECT *FROM products"); // check for empty result if ($result && mysql_num_rows($result) > 0) { // looping through all results // products node $response["products"] = array(); while ($row = mysql_fetch_array($result)) { // temp user array $product = array(); $product["pid"] = $row["pid"]; $product["name"] = $row["name"]; $product["price"] = $row["price"]; $product["created_at"] = $row["created_at"]; $product["updated_at"] = $row["updated_at"]; // push single product into final response array array_push($response["products"], $product); } // success $response["success"] = 1; } // Echo JSON anyway! echo json_encode($response); die(); ?>