Ответ Json очень медленный

Я пишу приложение для Android, которому иногда нужно загружать строку json размером около 1 МБ, содержащую около 1000 элементов, и анализировать каждый из них в базе данных 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();
            }
        }

person Rahul    schedule 01.09.2014    source источник
comment
покажи нам свое решение, может быть. 3 минуты звучит как невозможно   -  person Marcin Mikołajczyk    schedule 01.09.2014
comment
Если вы контролируете данные, вы можете рассмотреть возможность загрузки по частям, чтобы вы могли постепенно заполнять свою базу данных.   -  person stealthjong    schedule 01.09.2014
comment
проверьте мой обновленный код   -  person Rahul    schedule 01.09.2014
comment
Используйте Traceview, отчеты журнала и т. д., чтобы определить точно, в чем проблема. Также обратите внимание, что ваш код не выполняет синтаксический анализ, поэтому, если вы уже определили, что синтаксический анализ является вашей проблемой, этот код не будет иллюстрировать это. И имейте в виду, что HttpClient не рекомендуется Google.   -  person CommonsWare    schedule 01.09.2014
comment
Измеряли ли вы время получения ответа сервера и время разбора json? Любые задержки синтаксического анализа будут незначительными по сравнению со временем, необходимым для получения данных с сервера. Сколько времени требуется, чтобы получить ответ из другого места (например, в Fiddler) Если сервер обрабатывает запрос медленно, ничего не поделаешь. Принимает ли веб-сервис параметры OData для разделения данных на части? Слишком много вопросов, чтобы ответить   -  person Alexander Zhak    schedule 01.09.2014


Ответы (5)


Не используйте асинхронную задачу в таком случае, используйте собственный поток Java здесь.

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

             // Do your work .....

        }
    }).start();  

Когда нужно обновить пользовательский интерфейс. Да! Android не позволит вам сделать это. Итак... решение: ИСПОЛЬЗОВАТЬ обработчик для этого :)

 Handler handler = new Handler(); 

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

           // Do Update your UI     

       }    
 });

Используйте AsyncTask для:

  1. Простые сетевые операции, не требующие загрузки большого количества
  2. данные Задачи, связанные с диском, которые могут занять более нескольких миллисекунд

Используйте потоки Java для:

  1. Сетевые операции, в которых задействованы средние и большие объемы данных (либо загрузка, либо загрузка)
  2. Задачи с высокой загрузкой процессора, которые необходимо выполнять в фоновом режиме.
  3. Любая задача, в которой вы хотите контролировать использование ЦП относительно потока графического интерфейса.
person Mohsin    schedule 01.09.2014
comment
этот метод довольно медленный по сравнению с простым потоком Java - пожалуйста, отредактируйте свой вопрос, чтобы предоставить доказательство этого утверждения. - person CommonsWare; 01.09.2014
comment
братан! вы можете проверить это; уже обсуждалось во многих местах stackoverflow.com/a/18480297/3819810... Также есть несколько ссылок, вы можете проверяйте подробно :) - person Mohsin; 01.09.2014
comment
В этом ответе не говорится, что AsyncTask работает медленно по сравнению с простым java-потоком. Пожалуйста, отредактируйте свой вопрос, чтобы предоставить доказательство вашего утверждения о том, что AsyncTask (который в основном представляет собой простой поток Java) медленнее, чем простой поток Java. - person CommonsWare; 01.09.2014
comment
хорошо понял суть. да! говорить медленно не хорошо. редактирование сделано :) - person Mohsin; 01.09.2014

Вы также можете использовать GSON от Google.

person esoxjem    schedule 01.09.2014
comment
Можете ли вы привести какой-либо пример для библиотеки Джексона. Как пользоваться библиотекой Джексона?? - person Rahul; 02.09.2014
comment
Разница между библиотекой Джексона и GSON.?? - person Rahul; 02.09.2014
comment
Jackson и Gson — наиболее полные пакеты Java JSON в отношении фактической поддержки привязки данных. - person esoxjem; 05.09.2014

Попробуйте использовать библиотеку Джексона для управления вашим JSON. Это действительно эффективно. Вы можете найти его здесь: http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-jaxrs

Я использую его для файла размером 400 КБ менее 1 секунды.

Если вам нужен туто, этот выглядит хорошо http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/

person Eliott Roynette    schedule 01.09.2014
comment
Меняю ссылку на репозиторий maven, где можно скачать последнюю версию. - person Eliott Roynette; 01.09.2014

Вот как JSON читается в моем списке в моем приложении. Результат обрабатывается в моем приложении в среднем за 3 секунды по Wi-Fi и 5 секунд по 3G:

открытый класс CoreTeamFragment расширяет ListFragment {ArrayList> memberList; private String url_all_leaders = //Здесь идет URL private 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);
            }
        });
    }
}

}

person Michele La Ferla    schedule 01.09.2014

Используйте Volley или Retrofit lib.

Эти библиотеки увеличивают скорость.

Залп:

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();
}
person Ramesh Thangaraj    schedule 01.09.2014