Android 直接使用输入流解析json
我正在做一个api调用,作为响应,我得到了json。因此,我想通过输入流直接解析它,这样就不需要将它存储在内存中。 为此,我尝试使用JSONReader,但api小于11时,我无法使用它。 所以我不知道如何继续。我希望它是从2.0版开始。甚至通过JsonReader进行解析也不起作用。 我很想拥有GSON解析器,但我不知道如何用Inputstream实现同样的功能 编辑: 我的相同代码:Android 直接使用输入流解析json,android,json,gson,android-parser,Android,Json,Gson,Android Parser,我正在做一个api调用,作为响应,我得到了json。因此,我想通过输入流直接解析它,这样就不需要将它存储在内存中。 为此,我尝试使用JSONReader,但api小于11时,我无法使用它。 所以我不知道如何继续。我希望它是从2.0版开始。甚至通过JsonReader进行解析也不起作用。 我很想拥有GSON解析器,但我不知道如何用Inputstream实现同样的功能 编辑: 我的相同代码: HttpClient client = new DefaultHttpClient(); HttpGet h
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
Log.e("123", "Status code ----------- "+statusCode);
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
// for showing it on textview i am storing in in builder
BufferedReader bReader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = bReader.readLine()) != null) {
builder.append(line);
}
////////////
JsonReader reader = new JsonReader(new InputStreamReader(content));
reader.setLenient(true);
readGson(reader);
} else {
Log.e("TAG", "Failed to download file");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return builder.toString();
}
private void readGson(JsonReader reader) {
// TODO Auto-generated method stub
Log.e("TAG", "inidde readgson"+reader);
try {
Log.e("TAG", "inside try");
reader.beginObject();
Log.e("123", "inside try ");
while(reader.hasNext()){
Log.e("TAG", "reader values"+reader);
String name = reader.nextName();
if (name.equals("max_id")) {
long max_id = reader.nextLong();
Log.e("TAG", "sdbfhsajfgsdjbgksdfjv------------------"+max_id);
} else {
Log.e("TAG", "c skfnvklsfvn skip value");
reader.skipValue();
}
}
reader.endObject();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("TAG", "inside catch");
e.printStackTrace();
}
}
输出:
01-28 10:20:53.519: E/TAG(420): Status code ----------- 200
01-28 10:20:53.679: E/TAG(420): inidde readgsonJsonReader at line 1 column 1
01-28 10:20:53.679: E/TAG(420): inside try
01-28 10:20:53.679: E/TAG(420): inside catch
01-28 10:20:53.679: W/System.err(420): java.io.EOFException: End of input at line 1 column 1
01-28 10:20:53.689: W/System.err(420): at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:954)
01-28 10:20:53.689: W/System.err(420): at com.google.gson.stream.JsonReader.consumeNonExecutePrefix(JsonReader.java:405)
01-28 10:20:53.689: W/System.err(420): at com.google.gson.stream.JsonReader.peek(JsonReader.java:364)
01-28 10:20:53.689: W/System.err(420): at com.google.gson.stream.JsonReader.expect(JsonReader.java:337)
01-28 10:20:53.689: W/System.err(420): at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:322)
01-28 10:20:53.689: W/System.err(420): at com.example.httpconnectiondemo.MainActivity.readGson(MainActivity.java:136)
01-28 10:20:53.699: W/System.err(420): at com.example.httpconnectiondemo.MainActivity.readTwitterFeed(MainActivity.java:116)
01-28 10:20:53.699: W/System.err(420): at com.example.httpconnectiondemo.MainActivity.onCreate(MainActivity.java:64)
01-28 10:20:53.699: W/System.err(420): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-28 10:20:53.699: W/System.err(420): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
01-28 10:20:53.699: W/System.err(420): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
01-28 10:20:53.699: W/System.err(420): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
01-28 10:20:53.699: W/System.err(420): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
01-28 10:20:53.699: W/System.err(420): at android.os.Handler.dispatchMessage(Handler.java:99)
01-28 10:20:53.699: W/System.err(420): at android.os.Looper.loop(Looper.java:123)
01-28 10:20:53.699: W/System.err(420): at android.app.ActivityThread.main(ActivityThread.java:3683)
01-28 10:20:53.710: W/System.err(420): at java.lang.reflect.Method.invokeNative(Native Method)
01-28 10:20:53.710: W/System.err(420): at java.lang.reflect.Method.invoke(Method.java:507)
01-28 10:20:53.710: W/System.err(420): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-28 10:20:53.710: W/System.err(420): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-28 10:20:53.710: W/System.err(420): at dalvik.system.NativeStart.main(Native Method)
提前感谢。您以错误的方式使用了
内容流。请看标记的行:
InputStream content = entity.getContent();
// (1)
BufferedReader bReader = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = bReader.readLine()) != null) {
builder.append(line);
}
// (2)
JsonReader reader = new JsonReader(new InputStreamReader(content));
reader.setLenient(true);
readGson(reader);
这里的问题是将同一个流包装两次(在标记行上)
- 在第一次换行之后,您将通过流收集行并在
生成器中连接它们。您必须知道,bReader
实际上只是内容
流的包装器。因此,当您收集行时,将吃掉content
流中的内容。因此,条件(line=…)!=当内容
流位于输入端时,null
为假
- 然后再次包装
内容
流-用于解析JSON内容。但是流已经在这里输入的末尾了,因此JSON阅读器没有任何东西可以使用。这正是这一行的含义:java.io.eofeexception:exception的第1行第1列的输入结束
您需要做的是只阅读一次内容流。因此,这里有几个选项:
- 不要将收到的内容保存到
字符串中。您可以删除第一个换行和使用builder
构建响应字符串的循环。如果这不是一个选项,那么我建议:
- 将整个响应保存到
字符串中。注意:您可以为此使用EntityUtils
类,因为它将为您完成以下工作:
HttpEntity entity = response.getEntity();
// All the work is done for you here :)
String jsonContent = EntityUtils.toString(entity);
// Create a Reader from String
Reader stringReader = new StringReader(jsonContent);
// Pass the string reader to JsonReader constructor
JsonReader reader = new JsonReader(stringReader);
reader.setLenient(true);
readGson(reader);
...
// at the end of method return the JSON response
return jsonContent;
回答得好,伙计。这是非常清晰的,但有些东西确实让我感到困惑:为什么你建议不要保存一些东西到字符串(我认为是一个好的软件设计选择),在下一个主题中你建议把整个响应保存到一个字符串中。“Miere,你说得对,谢谢你指出不一致性:”让我解释一下我的意思。我的建议是不要将响应内容保存在字符串中
,这来自于我使用Android设备的经验,其中一些设备的内存限制非常低,例如16M/应用程序。现在想象一个应用程序试图保存JSON响应,比如说,有2000万个。。。应用程序将崩溃。我不知道OP的目标是什么设备,这就是我写第一点的原因。但是,在某些情况下,您知道这种情况不会发生,您可以安全地执行第二点。@andr perfect!非常感谢您的澄清。