I am doing a project where I need to parse JSON from a URL through HttpClient. My code works fine for JSON object responses with a small amount of data. But when I use the same code to get a response with a huge amount of data (more than 3MB), I have a problem.
Here is my code:
JSONfunctions.java (function for json parsing)
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
//import java.util.HashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
//import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
//import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
import android.widget.Toast;
#SuppressWarnings("unused")
public class JSONfunctions {
public static JSONObject getJSONfromURL(String url){
InputStream is = null;
String result = "";
JSONObject jArray = null;
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
//convert response to string
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();
result=sb.toString();
// Toast.makeText(getBaseContext, result, Toast.LENGTH_LONG).
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
try{
jArray = new JSONObject(result);
}catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return jArray;
}
}
ListJson.java
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
//import org.w3c.dom.Document;
//import org.w3c.dom.Element;
//import org.w3c.dom.NodeList;
import android.app.ListActivity;
import android.content.Intent;
//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.Toast;
public class ListJson extends ListActivity {
public static JSONObject json;
public static JSONArray data;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list1);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
// String semail = "partha#excoflare.com";
// String spassword = "partha123";
// Toast.makeText(getApplicationContext(), JSONExample2.strEmail, Toast.LENGTH_LONG).show();
//Toast.makeText(getApplicationContext(), JSONExample2.strPwd, Toast.LENGTH_LONG).show();
//
json = JSONfunctions.getJSONfromURL("url here");
try{
data = json.getJSONArray("server_list");
for(int i=0;i<data.length();i++){
HashMap<String, String> map = new HashMap<String, String>();
JSONObject e = data.getJSONObject(i);
map.put("id", String.valueOf(i));
map.put("name", "" + e.getString("ServUser"));
map.put("email", "" + e.getString("ServURL"));
mylist.add(map);
}
}catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
// try {
// JSONObject newObject=json.getJSONObject("subscription");
// JSONArray data1 = newObject.getJSONArray("cust_product");
//
// Toast.makeText(getApplicationContext(), data1.toString(), Toast.LENGTH_LONG).show();
//
// for(int i=0;i<data1.length();i++){
// HashMap<String, String> map1 = new HashMap<String, String>();
// JSONObject e = data.getJSONObject(i);
//
// map1.put("id", String.valueOf(i));
// map1.put("name", "" + e.getString("ServUser"));
// map1.put("email", "" + e.getString("ServURL"));
// mylist.add(map1);
// }
//
// } catch (JSONException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.item_list,
new String[] { "name", "email" },
new int[] { R.id.item_title, R.id.item_subtitle });
setListAdapter(adapter);
final ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//#SuppressWarnings("unchecked")
//HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);
// Toast.makeText(ListJson.this, "ID '" + o.get("id") + "' was clicked.", Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), parent.getItemAtPosition(position).toString(),
Toast.LENGTH_LONG).show();
// String a= parent.getItemAtPosition(position).toString();
Intent intent2= new Intent(ListJson.this, ListJson2.class);
startActivity(intent2);
}
});
}
I am getting an OutOfMemoryException. I changed heap_size to 192MB and ram size to 32MB, but with no luck. How can I fix this?
Big amounts of data of JSON must be cut to smaller pieces. For example you have a 50000 products on your database. Then it's wise to paginate API requests - get this huge amount of products by 100-500 records on one query. That will solve your problem.
This approach solves one problem more - errors caused by internet and gprs connection loss etc.
If API is yours then you can change this. If not, then this is a big failure of API design and you can send change request.
EDIT:
Did a little reading and found that highly recommended for parsing huge load of JSON data is http://jackson.codehaus.org/ (Jackson Processor). Haven't tried it, so cannot comment about this library. Also recommend you to save this JSON stream into the file (don't load it to memory) and then parse it by chunks.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Im learning the JSON Parser. I follow the androidhive tutorial and copy its code, but sadly, i cannot. It does not display anything and has these type of errors:
11-22 17:27:12.132: E/AndroidRuntime(1938): Caused by: android.os.NetworkOnMainThreadException
Can anyone help me with this problem? Thanks.
JSONPaser
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;
}
}
MainActivity
import android.view.Menu;
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 MainActivity 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
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_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);
}
});
}
#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;
}
}
<uses-permission android:name="android.permission.INTERNET" /> is use in Manifest
How can i use AsyncTask or Thread with Handler to solve the error ?? do i need to delete my JSON Parser class ??
things i tried so far:
i switched i target SDK version to fit my emulator but it still
doesn't work
i run the project on my phone (Samsung) and emulator (Genymotion)
it show the same error
i tried to test another method without JSON Array
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
public class Main extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
try{ //try1 start
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// this is our TextView element, obtained by id from our XML layout
TextView myListView = (TextView)findViewById(R.id.netResult);
//lets try to connect
try{ //try2 start
//create a new client object
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://ephemeraltech.com/demo/android_tutorial20.php");
//execute the post and get the response object
HttpResponse response = httpclient.execute(httppost);
//get the message from the response
HttpEntity entity = response.getEntity();
//get the content of the message
InputStream webs = entity.getContent();
//convert response to string
try{ //try3 start
BufferedReader reader = new BufferedReader(new InputStreamReader(webs,"utf-8"),8);
//read one line of the response
myListView.setText(reader.readLine());
//slow our inputStream
webs.close();
}//try3 end
catch (Exception e){//catch 3 start
Log.e("log_result", "Error converting result "+e.toString());
}//catch 3 end
} //try2 end
catch (Exception e){//catch 2 start
Log.e("log_connect", "Error in http connection "+e.toString());
}
}//try1 end
catch (Exception e){ //catch 1 start
//this is the lie of code that sends a real error message to the log
Log.e("ERROR", "ERROR IN CODE: "+e.toString());
e.printStackTrace();
}//catch 1 end
}
#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;
}
}
in this code the LogCat catch my second try and print log_connect, Error in http connection
You have a NetworkOnMainThreadException error.
That means you have directly run your code on onCreate method:
But you can't update your data directly on MainUI thread.
For that you have to use AsyncTask or Thread with Handler or update your UI with runOnUiThread()
You can go with this:
http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html
Did you read the stack trace at all?
Caused by: android.os.NetworkOnMainThreadException
If you had even googled with "NetworkOnMainThreadException" you would have got the answer.
In short, the reason is you are performing an HTTP request on the main thread which is a bad practise actually. Android recently has become more restrictive and throws an exception.
What you need is something like this:
new AsyncTask<CustomParamClass, Void, String>() {
#Override
protected String doInBackground(final CustomerParamClass... params) {
//use params to get the data and make an HHTP Request.
}
#Override
protected void onPostExecute(final String params) {
// This is invoked on the main thread. Communicate here.
}
}.execute(<pass some params here>);
I have a strange issue with AsyncTask. I'm using an AsyncTask to load data from my website and create a ListView with theses datas. I set a listener to each item, when i click on an item i start a new activity.
But when my new activity is loaded, the old asynctask (from the first activity) reload and makes my application crash. (Because it tries to modify a ListView which don't exist anymore)
I tested the status of my AsyncTask and it never finish (always returning RUNNING but onPostExecute() is done)
package com.wglxy.example.dash1;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
import android.os.AsyncTask;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.SimpleAdapter;
public class F1Activity extends DashboardActivity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView (R.layout.activity_f2);
setTitleFromActivityLabel (R.id.title_text);
// Je démarre l'AsyncTask qui charge les interventions
getInterventionListing Listing = new getInterventionListing();
Listing.execute();
}
private class getInterventionListing extends AsyncTask<Integer, Integer, ArrayList<HashMap<String, String>>>
{
private ProgressDialog dialog;
#Override
protected void onPreExecute()
{
// Dialog qui s'affiche durant l'AsyncTask
dialog = ProgressDialog.show(F1Activity.this, "Chargement", "Chargement des données",true,true,new OnCancelListener() {
public void onCancel(DialogInterface dialog) {
dialog.dismiss();
cancel(true);
}});
}
#Override
protected ArrayList<HashMap<String, String>> doInBackground(Integer... params)
{
InputStream is = null;
String result = "";
String problemes = "";
String prenom = "";
String strURL = "http://monsiteweb.com/fichier.php";
ArrayList<HashMap<String, String>> listItem = new ArrayList<HashMap<String, String>>();
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("listing_intervention",""));
// Requête HTTP
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(strURL);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection " + e.toString());
}
HashMap<String, String> map;
// Convertion de la requête en string
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();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result " + e.toString());
}
// Parse des données JSON
try{
JSONArray jArray = new JSONArray(result);
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
if (json_data.getString("problemes") != "null")
problemes = json_data.getString("problemes");
if (json_data.getString("prenom") != "null")
prenom = json_data.getString("prenom");
map = new HashMap<String, String>();
map.put("titre", "N°" + json_data.getInt("id_intervention") + " : " + json_data.getString("nom") + " " + prenom);
map.put("description", problemes);
map.put("id_intervention", json_data.getString("id_intervention"));
map.put("id_client", json_data.getString("id_client"));
if (json_data.getInt("statut") == 0)
{
map.put("img", String.valueOf(R.drawable.onwork));
}
else if (json_data.getInt("statut") == 2)
{
map.put("img", String.valueOf(R.drawable.onwait));
}
else if (json_data.getInt("statut") == 6)
{
map.put("img", String.valueOf(R.drawable.home));
}
else
{
map.put("img", String.valueOf(R.drawable.other));
}
listItem.add(map);
}
}catch(JSONException e){
Log.e("log_tag", "Error parsing data " + e.toString());
}
return listItem;
}
#Override
protected void onPostExecute(ArrayList<HashMap<String, String>> listItem)
{
ListView maListViewPerso = (ListView) findViewById(R.id.listviewperso);
SimpleAdapter mSchedule = new SimpleAdapter (F1Activity.this, listItem, R.layout.listview,
new String[] {"img", "titre", "description"}, new int[] {R.id.img, R.id.titre, R.id.description});
maListViewPerso.setAdapter(mSchedule);
maListViewPerso.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
ListView maListViewPerso = (ListView) findViewById(R.id.listviewperso);
HashMap<String, String> items_loaded = (HashMap<String, String>) maListViewPerso.getItemAtPosition(position);
Intent defineIntent = new Intent(F1Activity.this, Details_intervention.class);
Bundle objetbundle = new Bundle();
objetbundle .putString("id_intervention",items_loaded.get("id_intervention").toString());
objetbundle .putString("id_client",items_loaded.get("id_client").toString());
defineIntent.putExtras(objetbundle );
F1Activity.this.startActivity(defineIntent);
}
});
dialog.dismiss();
}
}
}
-
03-03 16:58:27.300: W/dalvikvm(656): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
03-03 16:58:27.320: E/AndroidRuntime(656): FATAL EXCEPTION: main
03-03 16:58:27.320: E/AndroidRuntime(656): java.lang.NullPointerException
03-03 16:58:27.320: E/AndroidRuntime(656): at com.wglxy.example.dash1.F1Activity$getInterventionListing.onPostExecute(F1Activity.java:164)
03-03 16:58:27.320: E/AndroidRuntime(656): at com.wglxy.example.dash1.F1Activity$getInterventionListing.onPostExecute(F1Activity.java:1)
03-03 16:58:27.320: E/AndroidRuntime(656): at android.os.AsyncTask.finish(AsyncTask.java:602)
If you still need assistance...
Can you post the code for the Activity you are calling through onClick -- Details_intervention.class ?
A couple notes:
You can start the activity by just having startActivity(defineIntent), you dont need F1Activity.this.
Not to be picky, but you are breaking some java coding conventions throughout. Although it wont hurt the app, some things are not standard and just weird at first glance: An example is private class getInterventionListing - Classes should start with a capital letter and the preface "get" and "set" are used for methods only. So private class DownloadInterventionListing would be better.
I have tried to use Gson and another method to get the Json from my localhost and , but still can't done it. One of the method that I have tried is as follow which I see the code from web , it is divided into two java, it fianlly comes out that
" Error parsing data org.json.JSONException: Value [{"Age":18},{"Age":18},{"Age":18}] of type org.json.JSONArray cannot be converted to JSONObject " which [{"Age":18},{"Age":18},{"Age":18}] is the test data that I want to output what is the problem behind?
package com.pxr.tutorial.json;
import java.io.BufferedReader;
import java.io.InputStream;
java.io.InputStreamReader;
import java.util.HashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONfunctions {
public static JSONObject getJSONfromURL(String url){
InputStream is = null;
String result = "";
JSONObject jArray = null;
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
//convert response to string
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();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
try{
jArray = new JSONObject(result);
}catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return jArray;
}
}
package com.pxr.tutorial.json;
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import com.pxr.tutorial.xmltest.R;
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.Toast;
public class Main extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listplaceholder);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
JSONObject json = JSONfunctions.getJSONfromURL("http://10.0.2.2:28750/User/JsonIndex");
try{
JSONArray earthquakes = json.getJSONArray("Age");
for(int i=0;i<age.length();i++){
HashMap<String, String> map = new HashMap<String, String>();
JSONObject e = earthquakes.getJSONObject(i);
map.put("id", String.valueOf(i));
map.put("name", "Earthquake name:" + e.getString("eqid"));
map.put("magnitude", "Magnitude: " + e.getString("magnitude"));
mylist.add(map);
}
}catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.main,
new String[] { "name", "magnitude" },
new int[] { R.id.item_title, R.id.item_subtitle });
setListAdapter(adapter);
final ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
#SuppressWarnings("unchecked")
HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);
Toast.makeText(Main.this, "ID '" + o.get("id") + "' was clicked.", Toast.LENGTH_SHORT).show();
}
});
}
}`
I am developing a final year project and I am stuck at a point. I have to retrieve names of doctors from my database (MySQL database) and show it in a list view. I was able to establish a connection with the server and retrieve values, but when I tried to show the values in a list view, the application crashed!
I tried the same example given in [Hello, Views, List View][4].
It works for a predefined array like
private String lv_arr[]={"Android","iPhone","BlackBerry","AndroidPeople"};
but for a string array retrieved from the database it shows a run time exception. Is there any way I can achieve this?
package com.proj;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.widget.*;
import android.app.ListActivity;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.TextView;
public class proj extends ListActivity {
/** Called when the activity is first created. */
public int n=0;
public int t=0;
public int i=0;
public String name[]=new String[30];
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create a crude view - this should really be set via the layout resources
// but since its an example saves declaring them in the XML.
TextView txt=(TextView)findViewById(R.id.tv);;
//Call the method to run the data retrieval
getServerData(KEY_121);
setListAdapter(new ArrayAdapter(this,
android.R.layout.simple_list_item_1, name));
}
public static final String KEY_121 = "http://10.0.2.2/doc.php"; //I use my real IP address here.
private String getServerData(String returnString) {
InputStream is = null;
String result = "";
//The year data to send.
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("year","1970"));
//HTTP post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(KEY_121);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}
catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
//Convert response to string
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();
result=sb.toString();
}
catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
//Parse JSON data
try {
JSONArray jArray = new JSONArray(result);
for(i=0;i<jArray.length();i++)
{
JSONObject json_data = jArray.getJSONObject(i);
n=jArray.length();
name[i]=json_data.getString("name");
//Get an output to the screen
returnString += "\n\t" + jArray.getJSONObject(i);
}
}
catch(JSONException e)
{
Log.e("log_tag", "Error parsing data "+e.toString());
e.printStackTrace();
}
return returnString;
}
}
You are using
1.)
android:id="#+id/list"
inside the ListView, but if your extend an activity by ListActivity you have to use
android:id = "#android:id/list"
2.)
You return a String[] here, not String
private String[] getServerData(String returnString) {
.......
JSONArray jArray = new JSONArray(result);
name = new String[jArray.length()];
for(i=0;i<jArray.length();i++)
{
JSONObject json_data = jArray.getJSONObject(i);
name[i]=json_data.getString("name");
}
return name;
}
And in ArrayAdapter, do it like this:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getServerData(KEY_121));
setListAdapter(adapter);
public String name[];
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create a crude view - this should really be set via the layout resources
// but since its an example saves declaring them in the XML.
TextView txt=(TextView)findViewById(R.id.tv);;
...
...
try {
JSONArray jArray = new JSONArray(result);
name[]=new String[jArray.length()];
for(i=0;i<jArray.length();i++)
{
JSONObject json_data = jArray.getJSONObject(i);
n=jArray.length();
name[i]=json_data.getString("name");
//Get an output to the screen
returnString += "\n\t" + jArray.getJSONObject(i);
}
}
catch(JSONException e)
{
Log.e("log_tag", "Error parsing data "+e.toString());
e.printStackTrace();
}
It seems that initializing name[] with a size of 30 may be too small.
Here's the code for my JSON parsing app. It force closes as soon as I run it on my emulator. I am new to Android programming, and I'm self taught so please bear with me. Thanks!
JSONfunctions.java:
package com.pxr.tutorial.json;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class JSONfunctions {
public static JSONObject getJSONfromURL(String url){
InputStream is = null;
String result = "";
JSONObject jArray = null;
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
//convert response to string
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();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
try{
jArray = new JSONObject(result);
}catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return jArray;
}
}
Main.java:
package com.pxr.tutorial.json;
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import com.pxr.tutorial.xmltest.R;
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.Toast;
public class Main extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listplaceholder);
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String,
String>> ();
JSONObject json = JSONfunctions.getJSONfromURL
("http://www.tastekid.com/ask/ws?q=mosdef&f=musifin2125&k=mjjlnzkyzwuz&format=JSON");
try{
JSONArray similar = json.getJSONArray("similar");
for(int i=0;i<similar.length();i++){
HashMap<String, String> map = new HashMap<String, String>();
JSONObject e = similar.getJSONObject(i);
map.put("id", String.valueOf(i));
map.put("name", "Name:" + e.getString("name"));
map.put("type", "Type: " + e.getString("type"));
mylist.add(map);
}
}catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.main,
new String[] { "name", "type" },
new int[] { R.id.item_title, R.id.item_subtitle });
setListAdapter(adapter);
final ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
#SuppressWarnings("unchecked")
HashMap<String, String> o = (HashMap<String, String>)
lv.getItemAtPosition(position);
Toast.makeText(Main.this, "ID '" + o.get("id") + "' was clicked.",
Toast.LENGTH_SHORT).show();
}
});
}
}
EDIT - Fixed unhandled exception, but now it says "No data" when I try to parse the URL.
Thanks again!
Here are your mistakes:
JSONArray similar = json.getJSONArray("similar");
In parsing JSON you have to note that it's case sensitive, i see that your json object is Similiar but you try to get it as similiar.
Similiar is a JSON Object but you try to get it as a JSONArray
Here is the fix for your codes, i give you a fix to get Info inside Similiar object:
JSONObject earthquakes = json.getJSONObject("Similar");
JSONArray info = earthquakes.getJSONArray("Info");
for (int i = 0; i < info.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
JSONObject e = info.getJSONObject(i);
map.put("id", String.valueOf(i));
map.put("name", "Name:" + e.getString("Name"));
map.put("type", "Type: " + e.getString("Type"));
mylist.add(map);
}
Replace your code block inside try after JSONObject json = JSONFun.getJSONfromURL("http://www.tastekid.com/ask/ws? q=mosdef&f=musifin2125&k=mjjlnzkyzwuz&format=JSON");
with code above.
have you added the permission tag in your manifest file which allow the use of internet