【问题标题】:Json response is very slow androidJson响应很慢android
【发布时间】:2014-09-01 13:01:51
【问题描述】:

我正在编写一个 Android 应用程序,它偶尔需要下载一个大约 1MB 并包含大约 1000 个元素的 json 字符串,并将每个元素解析到一个 SQLite 数据库中,我用它来填充 ListActivity。

即使下载和解析不是每次与应用交互时都需要完成的事情(仅在首次运行或用户选择刷新数据时),我仍然担心解析部分是耗时太长,大约两到三分钟 - 从手机应用程序的角度来看,这似乎是永恒的!

我正在使用此代码... :-

            public class CustomerAsyncTask extends AsyncTask<String, Integer, String> {
            private Context context;
            private String url_string;
            private String usedMethod;
            private String identifier;
            List<NameValuePair> parameter;
            private boolean runInBackground;
            AsynTaskListener listener;
            private Bitmap bm = null;

            public ProgressDialog pDialog;
            public String entityUtil;
            int index = 0;
            public static int retry = 0;

            private String jsonString = "";

            private String DialogString = "";

            // use for AsyncTask web services-----------------
            public CustomerAsyncTask(Context ctx, String url, String usedMethod,
                    String identifier, boolean runInBackground, String DialogString,
                    List<NameValuePair> parameter, AsynTaskListener callack) {
                this.context = ctx;
                this.url_string = url;
                this.usedMethod = usedMethod;
                this.identifier = identifier;
                this.parameter = parameter;
                this.runInBackground = runInBackground;
                this.listener = callack;
                this.DialogString = DialogString;
            }

            public CustomerAsyncTask(Context ctx, String url, String usedMethod,
                    String identifier, boolean runInBackground,
                    List<NameValuePair> parameter, AsynTaskListener callack, Bitmap bm) {
                this.context = ctx;
                this.url_string = url;
                this.usedMethod = usedMethod;
                this.identifier = identifier;
                this.parameter = parameter;
                this.runInBackground = runInBackground;
                this.listener = callack;
                this.bm = bm;

            }

            @Override
            protected void onPreExecute() {
                // TODO Auto-generated method stub
                super.onPreExecute();
                if (runInBackground)
                    initProgressDialog(DialogString);
            }

            @Override
            protected void onProgressUpdate(Integer... values) {
                // TODO Auto-generated method stub
                super.onProgressUpdate(values);
            }

            @SuppressWarnings("deprecation")
            @Override
            protected String doInBackground(String... params) {
                HttpParams httpParameters = new BasicHttpParams();
                int timeoutConnection = 10000; // mili second
                HttpConnectionParams.setConnectionTimeout(httpParameters,
                        timeoutConnection);
                int timeoutSocket = 10000;
                HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
                DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
                try {
                    HttpResponse response = null;
                    if (usedMethod.equals(GlobalConst.POST)) {
                        HttpPost httppost = new HttpPost(this.url_string);
                        httppost.setHeader("Content-Type",
                                "application/x-www-form-urlencoded");
                        // Customer Login MObile
                        if (identifier.equals("Customer_Login")) {
                            if (params.length > 0) {
                                parameter = new ArrayList<NameValuePair>();
                                parameter.add(new BasicNameValuePair("cus_mob",
                                        params[0]));
                            }
                            httppost.setEntity(new UrlEncodedFormEntity(parameter));

                            // Customer Verify Code
                        } else if (identifier.equals("Customer_mob_verify")) {
                            if (params.length > 0) {
                                parameter = new ArrayList<NameValuePair>();
                                parameter.add(new BasicNameValuePair("cus_verify",
                                        params[0]));
                                parameter.add(new BasicNameValuePair("cus_mobile",
                                        params[1]));
                            }
                            httppost.setEntity(new UrlEncodedFormEntity(parameter));
                        } else if (identifier.equals("Dashboard")) {
                            if (params.length > 0) {
                                parameter = new ArrayList<NameValuePair>();
                                parameter.add(new BasicNameValuePair("cus_id",
                                        params[0]));
                            }
                            httppost.setEntity(new UrlEncodedFormEntity(parameter));
                        }
                        response = (HttpResponse) httpClient.execute(httppost);

                    } else if (usedMethod.equals(GlobalConst.GET)) {

                        HttpGet httpput = new HttpGet(this.url_string);
                        httpput.setHeader("Content-Type",
                                "application/x-www-form-urlencoded");
                        response = (HttpResponse) httpClient.execute(httpput);
                    }

                    // Buffer Reader------------------------
                    InputStream inputStream = null;
                    String result = null;
                    try {
                        HttpEntity entity1 = response.getEntity();
                        inputStream = entity1.getContent();
                        BufferedReader reader = new BufferedReader(
                                new InputStreamReader(inputStream, "UTF-8"), 8);
                        StringBuilder sb = new StringBuilder();
                        String line = null;
                        while ((line = reader.readLine()) != null) {
                            sb.append(line + "\n");
                        }
                        result = sb.toString();
                    } catch (Exception e) {
                    } finally {
                        try {
                            if (inputStream != null)
                                inputStream.close();
                        } catch (Exception squish) {
                        }
                    }
                    jsonString = result;
                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                    return AsyncResultConst.CONNEERROR;
                } catch (IOException e) {
                    e.printStackTrace();
                    return AsyncResultConst.CONNEERROR;
                } catch (Exception e1) {
                    e1.printStackTrace();
                    return AsyncResultConst.EXCEPTION;
                } finally {
                    httpClient.getConnectionManager().shutdown();
                }
                return AsyncResultConst.SUCCESS;
            }

            @Override
            protected void onPostExecute(String result) {
                // TODO Auto-generated method stub
                if (runInBackground)
                    pDialog.dismiss();
                if (result.equals(AsyncResultConst.SUCCESS)) {
                    listener.onRecieveResult(identifier, jsonString);
                } else if (result.equals(AsyncResultConst.PARSINGERROR)) {
                    // showAlertMessage(context, "Error", "Parsing Error", null);
                    listener.onRecieveException(identifier, result);
                } else {
                    if (retry < 0) {
                        retry++;
                        new CustomerAsyncTask(context, url_string, usedMethod,
                                identifier, runInBackground, DialogString, parameter,
                                listener).execute("");
                    } else {
                        // showAlertMessage(context, "Error", "Connection Error", null);
                        listener.onRecieveException(identifier, result);
                    }
                }
                super.onPostExecute(result);
            }

            private void initProgressDialog(String loadingText) {
                pDialog = new ProgressDialog(this.context);
                pDialog.setMessage(loadingText);
                pDialog.setCancelable(false);
                pDialog.show();
            }
        }

【问题讨论】:

  • 或许向我们展示您的解决方案。 3 分钟听起来不可能
  • 如果您正在控制数据,您可能需要考虑分批下载,以便逐步填充数据库。
  • 检查我更新的代码
  • 使用 Traceview、日志语句等来确定准确您的问题出在哪里。另请注意,您的代码没有进行任何解析,因此如果您已经确定解析是您的问题,那么此代码将不会说明这一点。请记住,Google 不推荐使用 HttpClient。
  • 你测量过服务器响应获取时间和json解析时间吗?与从服务器检索数据所需的时间相比,任何解析延迟都是微不足道的。从其他地方(例如在 Fiddler 中)获得响应需要多长时间如果服务器处理请求缓慢,则无济于事。 webservice 是否接受 OData 参数来拆分数据?要回答的问题太多了

标签: java android performance android-json


【解决方案1】:

在这种情况下不要使用 Async-task,这里使用本地 java 线程。

 new Thread(new Runnable() {
        public void run() {

             // Do your work .....

        }
    }).start();  

何时需要更新 UI。是的! Android 不允许您这样做。所以...解决方案是:为此使用处理程序:)

 Handler handler = new Handler(); 

 handler.post(new Runnable() {
      @Override
      public void run() {

           // Do Update your UI     

       }    
 });

将 AsyncTask 用于:

  1. 不需要大量下载的简单网络操作
  2. 可能需要超过几毫秒的数据磁盘绑定任务

将 Java 线程用于:

  1. 涉及中到大量数据的网络操作(上传或下载)
  2. 需要在后台运行的高 CPU 任务
  3. 您想要控制相对于 GUI 线程的 CPU 使用率的任何任务

【讨论】:

  • “与简单的 java 线程相比,这些技术非常缓慢”——请编辑您的问题以提供此声明的证据。
  • 兄弟!你可以检查一下;已经讨论了很多地方stackoverflow.com/a/18480297/3819810...还有一些参考链接,您可以详细查看:)
  • 这个答案并没有说AsyncTask 与“简单的java线程”相比很慢。请编辑您的问题,以证明您声称 AsyncTask(主要是“简单的 Java 线程”)比“简单的 Java 线程”慢。
  • 好的,明白了。是的!说慢是不好的。编辑完成:)
【解决方案2】:

您也可以使用 Google 的 GSON。

【讨论】:

  • 你能提供杰克逊图书馆的任何例子吗?如何使用杰克逊图书馆??
  • 杰克逊图书馆和 GSON 的区别 .??
  • Jackson 和 Gson 是关于实际数据绑定支持的最完整的 Java JSON 包。
【解决方案3】:

尝试使用 Jackson 库来管理您的 JSON。它真的很有效。你可以在这里找到它:http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-jaxrs

我用它来处理一个 400KB 的文件不到 1 秒。

如果你想要一个tuto,这个看起来不错http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/

【讨论】:

  • 我将链接更改为 maven 存储库,您可以在其中下载最新版本。
【解决方案4】:

这就是在我的应用程序中将 JSON 读取到我的列表视图中的方式。在 Wi-Fi 上平均 3 秒,在 3G 上平均 5 秒将结果处理到我的应用:

公共类 CoreTeamFragment 扩展 ListFragment { 数组列表>成员列表; private String url_all_leaders = //URL 放在这里 私有 ProgressDialog pDialog;

JSONParser jParser = new JSONParser();

// JSON Node names
private static final String CONNECTION_STATUS = "success";
private static final String TABLE_TEAM = "CoreTeam";
private static final String pid = "pid";
private static final String COL_NAME = "CoreTeam_Name";
private static final String COL_DESC = "CoreTeam_Desc";
private static final String COL_PIC = "CoreTeam_Picture";

JSONArray CoreTeam = null;

public static final String ARG_SECTION_NUMBER = "section_number";

public CoreTeamFragment() {
}

public void onStart() {
    super.onStart();

    membersList = new ArrayList<HashMap<String, String>>();
    new LoadAllMembers().execute();

    // selecting single ListView item
    ListView lv = getListView();

    // Lauching the Event details screen on selecting a single event
    lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            // getting values from selected ListItem
            String ID = ((TextView) view.findViewById(R.id.leader_id))
                    .getText().toString();

            Intent intent = new Intent(view.getContext(),
                    CoreTeamDetails.class);
            intent.putExtra(pid, ID);
            view.getContext().startActivity(intent);
        }
    });
}

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_coreteam,
            container, false);

    return rootView;
}

class LoadAllMembers extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(getActivity());
        pDialog.setMessage("Just a moment...");
        pDialog.setIndeterminate(true);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    protected String doInBackground(String... args) {
        // Building Parameters
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        // getting JSON string from URL
        JSONObject json = jParser.makeHttpRequest(url_all_leaders,
                "GET", params);

        try {
            // Checking for SUCCESS TAG
            int success = json.getInt(CONNECTION_STATUS);

            if (success == 1) {
                // products found
                // Getting Array of Products
                CoreTeam = json.getJSONArray(TABLE_TEAM);
                // looping through All Contacts
                for (int i = 0; i < CoreTeam.length(); i++) {
                    JSONObject ct = CoreTeam.getJSONObject(i);

                    // Storing each json item in variable
                    String id = ct.getString(pid);
                    String name = ct.getString(COL_NAME);
                    String desc = ct.getString(COL_DESC);
                    String pic = ct.getString(COL_PIC);

                    // creating new HashMap
                    HashMap<String, String> map = new HashMap<String, String>();

                    // adding each child node to HashMap key => value
                    map.put(pid, id);
                    map.put(COL_NAME, name);
                    map.put(COL_DESC, desc);
                    map.put(COL_PIC, pic);

                    // adding HashList to ArrayList
                    membersList.add(map);

                }
            } else {
                // Options are not available or server is down.
                // Dismiss the loading dialog and display an alert
                // onPostExecute
                pDialog.dismiss();
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(String file_url) {
        // dismiss the dialog after getting all products
        pDialog.dismiss();
        // updating UI from Background Thread
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                ListAdapter adapter = new SimpleAdapter(
                        getActivity(),
                        membersList,
                        R.layout.coreteam_item,
                        new String[] { pid, COL_NAME, COL_DESC, COL_PIC },
                        new int[] { R.id.leader_id, R.id.leaderName,
                                R.id.photo });
                setListAdapter(adapter);
            }
        });
    }
}

}

【讨论】:

    【解决方案5】:

    使用 Volley 或 Retrofit 库。

    那些库正在提高速度。

    凌空抽射:

    JsonObjectRequest channels = new JsonObjectRequest(Method.POST,
                    Constants.getaccountstatement + Constants.key, statement_object,
                    new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject arg0) { 
    }, new Response.ErrorListener()
            {
                @Override
                public void onErrorResponse(VolleyError e) {
                    Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
    }
    

    【讨论】:

      猜你喜欢
      • 2017-09-26
      • 2012-03-09
      • 1970-01-01
      • 2014-12-12
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      相关资源
      最近更新 更多