Reputation: 331
I have an app that loads data from a JSON URL, but it takes about 8 seconds to load and I believe this is because of parsing.
I want to know if is there a faster way to parse it faster and easier?
This is the function I am using to read the JSON:
public class LoadJson extends AsyncTask <String, Void, String> {
@Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
return finalJson;
} catch (Exception e) {
e.printStackTrace();
return "Faild";
}
}
}
and:
public JSONArray ExcuteLoad() {
LoadJson task = new LoadJson();
String resualt = null;
try {
resualt = task.execute("MY_JSON_FILE_URL").get();
JSONObject json = new JSONObject(resualt);
JSONArray jarray = json.getJSONArray("marcadores");
return jarray;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
UPDATE 1:
Ok folks i change the code base on what you suggested about using onPostExecute
but the problem is i can't return the value of jsonarray outside of asyncTask, got really confused....
public class LoadJson extends AsyncTask <String, Void, String> {
public class LoadJson extends AsyncTask <String, Void, String> {
public interface AsyncResponse {
void processFinish(String output);
}
public AsyncResponse delegate = null;
public LoadJson (AsyncResponse delegate){
this.delegate = delegate;
}
@Override
protected String doInBackground(String... params) {
String resualt = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(params[0]);
urlConnection = (HttpURLConnection)url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
resualt += current;
data = reader.read();
}
return resualt;
}
catch (Exception e) {
e.printStackTrace();
return "Failed";
}
}
@Override
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
}
and My Fragment class:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
LoadJson asyncTask = (LoadJson) new LoadJson (new LoadJson.AsyncResponse(){
@Override
public void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
try {
JSONObject jsonObject = new JSONObject(output);
JSONArray jsonArray = jsonObject.getJSONArray("marcadores");
} catch (JSONException e) {
e.printStackTrace();
}
}
}).execute();
Upvotes: 0
Views: 3321
Reputation: 191728
Your problem isn't parsing the JSON. You can't speed that up. Using a different library (probably) isn't going to make that faster either. (I'm talking about load times, not development time).
It comes down to how you make the request as well as your internet speed.
For example, this is not how you use an AsyncTask.
resualt = task.execute("MY_JSON_FILE_URL").get();
Because you just made an asynchronous call into a synchronous one. In other words, the get()
method will block and wait for a result, therefore taking time and cause the data to load slowly.
Now, sure, libraries reduce the complexity of AsyncTask and make development "faster and easier", but the quick answer here is to actually use onPostExecute
of the AsyncTask class to load the data asynchronously, off the main thread.
The best example I can give is Using a callback to return the data
Update
private JSONArray array;
private void parseJSON(JSONArray array) {
this.array = array;
// TODO: something
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
LoadJson asyncTask = (LoadJson) new LoadJson (new LoadJson.AsyncResponse(){
@Override
public void processFinish(String output){
//Here you will receive the result fired from async class
//of onPostExecute(result) method.
try {
JSONObject jsonObject = new JSONObject(output);
JSONArray jsonArray = jsonObject.getJSONArray("marcadores");
for (int i = 0; i < jsonArray.length; i++) {
// TODO: Parse the array, fill an arraylist
}
// TODO: Set / notify an adapter
// Or....
parseJSON(jsonArray);
} catch (JSONException e) {
e.printStackTrace();
}
}
}).execute();
Upvotes: 1