Я создаю приложение для Android, которое запускает ASP.NET WebService. Webservice отправляет объект JSON, и приложение анализирует объект и отображает его на экране. В одном случае объект JSON слишком велик, и я получаю ошибку транзакции Binding Binding. Мое решение состоит в том, чтобы получить этот объект JSON и вставить его в код приложения, чтобы ему не нужно было получать этот объект JSON с сервера. Можете ли вы рассказать о других вещах, которые я могу сделать для этой проблемы? Или вы можете сказать мне, как получить этот объект JSON из Webservice? Спасибо.
Как работать с большим объектом JSON на Android
Ответ 1
Отправка большого размера данных с сервера на мобильный. JSON - легкий вес. Если вы хотите передать данные, используя более эффективный способ, затем передайте его в разбивке на страницы. Если вы хотите использовать более легкий протокол, чем JSON, тогда выполните приведенный ниже протокол google, которые действительно полезны, которые поддерживают основные языки. Ниже представлена структура данных Serialized. Протокол обмена данными Google.
Надеюсь, это будет полезно вам.
Ответ 2
Если данные велики, попробуйте сохранить их в базе данных, а затем обработайте их с помощью SQLite. (но не рекомендуется, если его динамика)
Чтобы разобрать json-объект, используйте gson или jackson. Это значительно уменьшит потребление памяти, поскольку детали json будут разбираться частично. получите Гсона, Джексона здесь https://sites.google.com/site/gson/gson-user-guide http://jackson.codehaus.org/
Пример Джексона http://www.mkyong.com/java/jackson-streaming-api-to-read-and-write-json/
Ответ 3
Первое: если в коде есть авария или исключение, вы, вероятно, захотите опубликовать это. "Failed Binder Exception" слишком неопределенно, чтобы понять, что вы делаете.
Если вы действительно хотите отправить свое приложение для Android с помощью встроенного JSON внутри него (чтобы избежать необходимости извлекать его с сервера, подумайте о его сохранении как ресурсе и получите доступ к нему с помощью AssetManager. В основном вы удаляете файл с помощью json в папке с вашими приложениями и читаете их с помощью AssetManager.
Если вы все еще хотите загрузить его с сервера и действовать на нем, рассмотрите возможность использования потоковых API для загрузки и анализа JSON. Android JSONObject не делает этого, и он настаивает на том, что вся целая строка JSON в памяти перед ее анализом.
Если вы хотите напрямую передавать URL-адрес в потоковой парсер (например, GSON), попробуйте что-нибудь в этом направлении. Сначала получите InputStream из URL-адреса, который вы пытаетесь извлечь:
URL u = new URL(url);
URLConnection conn = u.openConnection();
InputStream is = new BufferedInputStream(conn.getInputStream());
Затем подайте этот InputStream прямо на ваш потоковой парсер. Это должно предотвратить необходимость вытащить весь ответ в память перед разбором, но вам все равно потребуется достаточно памяти, чтобы содержать все объекты, которые создает парсер:
GsonBuilder gb = new GsonBuilder(); // configure this as necessary
Gson gson = gb.create();
final Result response = gson.fromJson(
new InputStreamReader(is, Charset.forName("UTF-8")),
Result.class
);
"Результат" - это класс, который будет содержать данные из ответа JSON. Вы должны будете убедиться, что все сопоставления работают для ваших данных, поэтому читайте на GSON и делайте все, что работает для вашего дела.
Вы также можете использовать GSON для анализа данных JSON, если вы храните их в активе. Просто передайте его InputStream данных о ресурсах, и он работает одинаково.
Ответ 4
Передаете ли вы данные между действиями? Я имею в виду, вы пытаетесь передать большой объект данных (полученный от WS) в другое действие, используя aim.putExtra()?
Ответ 5
Вы можете встроить свой JSON в свой код приложения, как вы предложили, но это будет плохой подход, если JSON будет динамичным. Затем вам нужно будет нажать обновление для своего приложения, когда изменяется JSON.
Лучшим решением будет разбиение на страницы JSON, который вы создаете из своего WebService, т.е. разбить JSON на более мелкие части, которые вы можете выборочно выполнять в отдельных вызовах API.
Ответ 6
Желательно попытаться разбить объект Json на более мелкий объект и получить из webService,
или получить данные по частям, и если вы не можете сделать это
Вы должны использовать потоковый анализатор JSON. Для Android вы можете использовать эти 2:
-
GSON
-
Джексон
GSON Streaming объясняется по адресу: https://sites.google.com/site/gson/streaming
Мне лично нравится Gson.
Ответ 7
Следующий класс ApiUrlClass.java
имеет все необходимые вам методы. Прочтите комментарии к классу, который я написал. Это поможет вам сделать то, что вам нужно. Это также использует прозрачность.
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.StringBody;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLPeerUnverifiedException;
/*
Usage of the class
Create all the necessary API Call methods you need.
And either use a Thread or AsyncTask to call the following.
JSONObject response = ApiUrlCalls.login("username", "passowrd");
After the response is obtained, check for status code like
if(response.getInt("status_code") == 200){
//TODO: code something
} else {
//TODO: code something
}
*/
public class ApiUrlCalls {
private String HOST = "https://domain/path/"; //This will be concated with the function needed. Ref:1
/*
Now utilizing the method is so simple. Lets consider a login function, which sends username and password.
See below for example.
*/
public static JSONObject login(String username, String password){
String functionCall = "login";
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("username", username)
.appendQueryParameter("password", password);
/*
The return calls the apiPost method for processing.
Make sure this should't happen in the UI thread, orelse, NetworkOnMainThread exception will be thrown.
*/
return apiPost(builder, functionCall);
}
/*
This method is the one which performs POST operation. If you need GET, just change it
in like Connection.setRequestMethod("GET")
*/
private static JSONObject apiPost(Uri.Builder builder, String function){
try {
int TIMEOUT = 15000;
JSONObject jsonObject = new JSONObject();
try {
URL url = null;
String response = "";
/*
Ref:1
As mentioned, here below, in case the function is "login",
url looks like https://domain/path/login
This is generally a rewrited form by .htaccess in server.
If you need knowledge on RESTful API in PHP, refer
http://stackoverflow.com/info/34997738/creating-restful-api-what-kind-of-headers-should-be-put-out-before-the-response/35000332#35000332
I have answered how to create a RESTful API. It matches the above URL format, it also includes the .htaccess
*/
url = new URL(HOST + function);
HttpsURLConnection conn = null;
conn = (HttpsURLConnection) url.openConnection();
assert conn != null;
conn.setReadTimeout(TIMEOUT);
conn.setConnectTimeout(TIMEOUT);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
String query = builder.build().getEncodedQuery();
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(query);
writer.flush();
writer.close();
os.close();
conn.connect();
int responseCode = conn.getResponseCode();
String responseMessage = conn.getResponseMessage();
jsonObject.put("status_code", responseCode);
jsonObject.put("status_message", responseMessage);
/*The if condition below will check if status code is greater than 400 and sets error status
even before trying to read content, because HttpUrlConnection classes will throw exceptions
for status codes 4xx and 5xx. You cannot read content for status codes 4xx and 5xx in HttpUrlConnection
classes.
*/
if (jsonObject.getInt("status_code") >= 400) {
jsonObject.put("status", "Error");
jsonObject.put("msg", "Something is not good. Try again later.");
return jsonObject;
}
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = br.readLine()) != null) {
response += line;
}
//Log.d("RESP", response);
/*
After the actual payload is read as a string, it is time to change it into JSON.
Simply when it starts with "[" it should be a JSON array and when it starts with "{"
it is a JSONObject. That is what hapenning below.
*/
if(response.startsWith("[")) {
jsonObject.put("content", new JSONArray(response));
}
if(response.startsWith("{")){
jsonObject.put("content", new JSONObject(response));
}
} catch(UnknownHostException e) {
//No explanation needed :)
jsonObject.put("status", "UnknownHostException");
jsonObject.put("msg", "Check your internet connection");
} catch (SocketTimeoutException){
//This is when the connection timeouts. Timeouts can be modified by TIMEOUT variable above.
jsonObject.put("status", "Timeout");
jsonObject.put("msg", "Check your internet connection");
} catch (SSLPeerUnverifiedException se) {
//When an untrusted SSL Certificate is received, this happens. (Only for https.)
jsonObject.put("status", "SSLException");
jsonObject.put("msg", "Unable to establish secure connection.");
se.printStackTrace();
} catch (IOException e) {
//This generally happens when there is a trouble in connection
jsonObject.put("status", "IOException");
jsonObject.put("msg", "Check your internet connection");
e.printStackTrace();
} catch(FileNotFoundException e){
//There is no chance that this catch block will execute as we already checked for 4xx errors
jsonObject.put("status", "FileNotFoundException");
jsonObject.put("msg", "Some 4xx Error");
e.printStackTrace();
} catch (JSONException e){
//This happens when there is a troble reading the content, or some notice or warnings in content,
//which generally happens while we modify the server side files. Read the "msg", and it is clear now :)
jsonObject.put("status", "JSONException");
jsonObject.put("msg", "We are experiencing a glitch, try back in sometime.");
e.printStackTrace();
} return jsonObject;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}