Reputation: 1017
I am currently working on an application that needs to consume a very large amount of JSON Data and I am having an issue using the Jackson parser to do this. I have the following code in my Class where I need to parse the data:
HttpRequest request = HttpRequest.get("http://www.site.com/android/app/getAllUsers.php");
final Reader reader = request.reader();
final ObjectMapper mapper = new ObjectMapper();
final JsonFactory factory = mapper.getFactory();
class LoadAllUsers extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(VenuesListActivity.this);
pDialog.setMessage("Loading Users. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
try {
JsonParser jp = factory.createParser(reader);
while(jp.nextToken() == JsonToken.START_OBJECT) {
final User a = mapper.readValue(jp, User.class);
String fieldName = jp.getCurrentName();
if("users".equals(fieldName))
{
jp.nextToken();
while(jp.nextToken() != JsonToken.END_ARRAY)
{
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, a.ID);
map.put(TAG_DATA2, a.data1);
map.put(TAG_DATA3, a.data2);
...
// adding HashList to ArrayList
usersList.add(map);
}
}
}
} catch (JsonParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all venues
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
setListAdapter(adapter);
}
});
}
}
Then I have the POJO's setup in a Class as shown below:
public class User {
String ID;
String data1;
String data2;
...
public String getID() {
return ID;
}
public void setID(String iD) {
ID = iD;
}
public String getData1() {
return data1;
}
public void setData1(String data1) {
this.data1 = data1;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
...
}
Below I have attached my PHP file which collects the data from my database to pass when called:
<?php
// array for JSON response $response = array(); // include db connect class require_once __DIR__ . '/dbConnect.php'; // connecting to db $db = new DB_CONNECT(); // get all users from users table $result = mysql_query("SELECT * FROM accounts") or die(mysql_error()); // check for empty result if (mysql_num_rows($result) > 0) {
// looping through all results
// users node
$response["users"] = array();
while ($row = mysql_fetch_array($result)) {
// temp user array
$venue = array();
$venue["ID"] = $row["ID"];
$venue["data1"] = $row["data1"];
$venue["data2"] = $row["data2"];
...
// push single user into final response array
array_push($response["users"], $venue);
}
// success
$response["success"] = 1;
// echoing JSON response
echo json_encode($response); } else {
// no users found
$response["success"] = 0;
$response["message"] = "No users found";
// echo no users JSON
echo json_encode($response); } ?>
When I run my code I would expect everything to work fine however I get the following error messages:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.app.accs/com.app.accs.UsersListActivity}: android.os.NetworkOnMainThreadException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2173)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2297)
at android.app.ActivityThread.access$700(ActivityThread.java:152)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1282)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5328)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1125)
at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)
at libcore.net.http.HttpEngine.connect(HttpEngine.java:311)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
at libcore.net.http.HttpURLConnectionImpl.getHeaderField(HttpURLConnectionImpl.java:139)
at com.github.kevinsawicki.http.HttpRequest.header(HttpRequest.java:2025)
at com.github.kevinsawicki.http.HttpRequest.parameter(HttpRequest.java:2120)
at com.github.kevinsawicki.http.HttpRequest.charset(HttpRequest.java:2230)
at com.github.kevinsawicki.http.HttpRequest.reader(HttpRequest.java:1822)
at com.app.accs.UsersListActivity.<init>(UsersListActivity.java:107)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1319)
at android.app.Instrumentation.newActivity(Instrumentation.java:1071)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2164)
I hope someone can help me as the JSON file could contain an array of 15,000 user entries and I wanted to use this streaming process to improve performance. I am also not sure but this this could have something to do with the target SDK so the below is a little bit more info about the app:
android:minSdkVersion="11"
android:targetSdkVersion="17"
Thanks in advance.
****EDIT*****
Hi thanks for the replies and I have been looking into this a bit further and yes this ASync task is executed from the MainUI(onCreate) by the following code below:
if(user == null || user.equals("All")){
// Loading users in Background Thread
new LoadAllUsers().execute();
}else{
// Load something else
}
This basically looks at a piece of data being passed to this view called "user" and if the user object is empty or it has a value of "All" then I execute the LoadAllUsers ASync Task. If I cannot execute it from the main UI how can I do this using the data passed into this view?
Thanks for the help
Upvotes: 0
Views: 490
Reputation: 6714
Change this line of Code:
class LoadAllUsers extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(UsersListActivity.this);
......
}
......
Along with that, don't make Network calls on UI Thread and make seperate Async Classes
or Services
for doing all the tasks related to the Network calls.
Upvotes: 0
Reputation: 13223
Like MrTristan said, you are running a Network task on the UI Thread
. Network tasks tend to be long so Android requires you to do them on a background Thread. Your code seems to use AsyncTask
to parse JSON data, but not to perform the Network task. Also, you do not need to use the runOnUiThread()
on onPostExecute()
because onPostExecute()
already is running on the UI Thread
.
Upvotes: 0
Reputation: 740
the Caused by: android.os.NetworkOnMainThreadException
that you're seeing in that crash report is pointing you to the fact that you're doing this on the main UI thread.. no networking allowed so it's killing it. look in to the proper use of AsycTasks.
also, you should be on the main UI thread when you interact with dialogs. that could also be a point of failure
please edit your question to include (or specify) what you have at VenuesListActivity.java:107
since that is what the crash report is also pointing to.
Upvotes: 2