【问题标题】:Fastest way to parse JSON解析 JSON 的最快方法
【发布时间】:2016-09-01 14:00:46
【问题描述】:

我有一个从 JSON URL 加载数据的应用,但加载大约需要 8 秒,我相信这是因为解析。
我想知道是否有更快更简单的解析方法?

这是我用来读取 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";
        }

    }
}

和:

 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;
    }
}

更新 1:

好吧,伙计们,我根据您对使用 onPostExecute 的建议更改了代码,但问题是我无法在 asyncTask 之外返回 jsonarray 的值,真的很困惑....

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);
     }
 }

和我的片段类:

@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();

【问题讨论】:

  • 除了你正在做的奇怪的解析之外,你还有一个与task.execute().get()同步的任务
  • 您可以使用 Jackson 来解析 Json,因为它速度很快,而且大多数供应商都使用 Jakson 来解析 JSON,即。 DropBox,Box.....仅供参考:blog.takipi.com/…
  • 我相信这是因为解析 - 您认为这是解析器,但您不确定。检测您的代码并找出问题所在!
  • @MuratK。你相信如果我把它改成在 1 个函数中工作,它会工作得更快吗?

标签: android json jackson gson


【解决方案1】:

您的问题不是解析 JSON。你不能加快速度。使用不同的库(可能)也不会使速度更快。 (我说的是加载时间,而不是开发时间)。

这取决于您提出请求的方式以及您的网速。

例如,这不是您使用 AsyncTask 的方式。

resualt = task.execute("MY_JSON_FILE_URL").get();

因为您刚刚将异步调用变为同步调用。换句话说,get() 方法会阻塞并等待结果,因此会花费时间并导致数据加载缓慢。

现在,当然,库降低了 AsyncTask 的复杂性并使开发“更快、更容易”,但这里的快速答案是实际使用 AsyncTask 类的onPostExecute 异步加载数据,脱离主线程。

我能举出的最好例子是Using a callback to return the data


更新

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();

【讨论】:

  • 你是对的,但问题是我必须在以下代码中执行所有代码:@Override void processFinish(String output){ 否则我无法访问从 asynctask 传递并执行的变量这个覆盖函数中的代码是另一个痛苦......!
  • 您可以在doInBackground中进行网络请求并将响应解析为JSONObject。您可以将 JSONObject 返回到 onPostExecute(而不是 processFinish)。从那里,您更新 UI 线程。这就是 AsyncTask 的工作原理。存在其他选项,如 Volley、OkHttp 和 Retrofit,但这是没有外部库的答案
  • 是的,但是我在一个单独的类中使用 AsyncTask 并想将它传递给我的片段类,如果它们都在一个类中,那就是现在的问题,是的,但是它们是分开的
  • 您是否阅读了我答案底部的链接?完美解决了分离类问题
  • 好的,我更新了我的帖子并尝试了你的方法,但它不适合我,请看看并告诉我出了什么问题:(
猜你喜欢
  • 2020-08-27
  • 1970-01-01
  • 2015-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-25
相关资源
最近更新 更多