#android #json
#Android #json
Вопрос:
Мое приложение для Android использует этот код для чтения и импорта 4700 записей из базы данных mysql в Интернете с помощью JSONArray :
@Override
protected String doInBackground(Void... params) {
try{
httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://www.example.com/preleva_prodotti.php");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
//Log.e("log_tag", "Error in http connection " e.toString());
httpclient.getConnectionManager().shutdown();
return result = "no_server";
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
String k = reader.readLine();
while ((line = k) != null) {
sb.append(line "n");
}
is.close();
result=sb;
}catch(Exception e){
return result = "no_server";
}
//parse json data
try{
JSONObject json= new JSONObject(result);
JSONArray jArray = json.getJSONArray("array");
return is_full="ok_insert";
}catch(JSONException e){
Log.e("log_tag", "Error parsing data " e.toString());
return is_full = "no_dati";
}
}
но в строке :
while ((line = k) != null) {
sb.append(line "n");
}
возникает ошибка: не хватает памяти.
Как можно решить эту проблему?
Комментарии:
1. В вашем коде вы пытались сохранить весь текст json в string object, а затем начать его синтаксический анализ в json. Некоторые библиотеки json (jackson, gson) поддерживают потоковый синтаксический анализ. Поэтому я думаю, что потоковый синтаксический анализ может решить вашу проблему с памятью. С помощью потокового синтаксического анализа вы можете начать синтаксический анализ json без необходимости для всех данных в памяти.
2. Как насчет того, чтобы не импортировать 4700 записей за раз, возможно, вы используете всю память для приложения или на телефоне. Я бы запрашивал его по частям.
Ответ №1:
Я не слишком знаком с Java, так что потерпите, но это, похоже, не зависит от языка.
Тем не менее, проблема, похоже, в том, что k
она никогда не обновляется. После k
назначения ( k = reader.readLine()
) вы (на неопределенный срок) повторно присваиваете line
то же значение (таким образом, бесконечный цикл, следовательно, не хватает памяти).
Я думаю, вы ищете:
String k = reader.readLine();
while ((line = k) != null) {
sb.append(line "n");
k = reader.readLine(); // or some facsimile
}
Обратите внимание, что теперь я переназначаю k
(хотя я не уверен, что избыточность наличия k
= line
; кажется пустой тратой переменной, имхо)
Комментарии:
1. Если, каким-то образом,
k
не станет синонимом вызоваreader.readLine()
, это проблема, которую я вижу…2. нет, проблема в строке sb.append, потому что k слишком длиннее для StringBuilder, но я не знаю, как решить эту проблему….
3. Вы уверены, что это
line
имеет слишком большое значение, а не то, чтоsb
достигло порога буфера?4. Мне трудно поверить, что одна строка файла превышает возможности
Append
метода, но я поверю вам на слово. С учетом сказанного я бы ознакомился с этой статьей о том, как избежать этого с помощью потоков.5. @Brad верен, у вас бесконечный цикл в этом коде, вы получите ошибку оом при чтении 1-строчного json-файла, подобного этому.