Blacksword
Blacksword

Reputation: 331

Fastest way to parse JSON

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

Answers (1)

OneCricketeer
OneCricketeer

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

Related Questions