GSON:END_OBJECT 永远不会被调用

Posted

技术标签:

【中文标题】GSON:END_OBJECT 永远不会被调用【英文标题】:GSON: END_OBJECT never get called 【发布时间】:2015-01-06 12:37:04 【问题描述】:

我有一个类似的 JSON:

"aData":

“锦标赛”:

“新”:[

"token":"1-token", "prio":"6", "status":"inactive", ..., "_timeCreated":"2014-04-14 14:44:49" , "_timeChanged":"2014-08-08 12:30:20",

"token":"2-token","prio":"8","status":"inactive",...

]

JSON 文件大小为 8 MB,并且有效,因为它可以使用默认的 new JSONObject(str)Volley's JsonObjectRequest 进行解析。

我使用的代码:

 reader = new JsonReader( new InputStreamReader( am.open( "updatedata.json" ) ) );
 reader.setLenient( true );
 while( reader.hasNext() )
   eachToken( reader );
   Log.i( TAG, "has next " + reader.hasNext() );
 

private boolean eachToken( JsonReader reader ) throws IOException 
  JsonToken token = reader.peek();
  switch( token )
    case BEGIN_ARRAY:
      reader.beginArray();
      Log.i( TAG, "array <<" );
      break;
    case END_ARRAY:
      reader.endArray();
      Log.i( TAG, "array >>" );
      break;
    case BEGIN_OBJECT:
      reader.beginObject();
      Log.i( TAG, "" );
      break;
    case END_OBJECT:
      reader.endObject();
      Log.i( TAG, "" );
      break;
    case NAME:
      String name = reader.nextName();
      Log.i( TAG, name );
      break;
    case STRING:
      String s = reader.nextString();
      Log.i( TAG, s );
      break;
    case NUMBER:
      int n = reader.nextInt();
      Log.i( TAG, "" + n );
      break;
    case BOOLEAN:
      boolean b = reader.nextBoolean();
      Log.i( TAG, "" + b );
      break;
    case NULL:
      reader.nextNull();
      Log.i( TAG, "null" );
      break;
    case END_DOCUMENT:
      Log.i( TAG, "end doc" );
      return false;
    default:
      Log.i( TAG, token.toString() );
  
  return true;

问题是,END_OBJECT 的情况从未达到。它将以下内容打印到logcat

  01-06 13:30:32.817: I/DataService(1819): 
  01-06 13:30:32.817: I/DataService(1819): has next true
  01-06 13:30:32.817: I/DataService(1819): aData
  01-06 13:30:32.817: I/DataService(1819): has next true
  01-06 13:30:32.817: I/DataService(1819): 
  01-06 13:30:32.817: I/DataService(1819): has next true
  01-06 13:30:32.817: I/DataService(1819): tournaments
  01-06 13:30:32.817: I/DataService(1819): has next true
  01-06 13:30:32.817: I/DataService(1819): 
  01-06 13:30:32.817: I/DataService(1819): has next true
  01-06 13:30:32.817: I/DataService(1819): new
  01-06 13:30:32.817: I/DataService(1819): has next true
  01-06 13:30:32.817: I/DataService(1819): array <<
  01-06 13:30:32.817: I/DataService(1819): has next true
  01-06 13:30:32.817: I/DataService(1819): 
  01-06 13:30:32.817: I/DataService(1819): has next true
  01-06 13:30:32.827: I/DataService(1819): token
  01-06 13:30:32.827: I/DataService(1819): has next true
  01-06 13:30:32.827: I/DataService(1819): 1-token
  01-06 13:30:32.827: I/DataService(1819): has next true
  01-06 13:30:32.827: I/DataService(1819): prio
  01-06 13:30:32.827: I/DataService(1819): has next true
  01-06 13:30:32.827: I/DataService(1819): 6
  01-06 13:30:32.827: I/DataService(1819): has next true
  01-06 13:30:32.827: I/DataService(1819): status
  01-06 13:30:32.827: I/DataService(1819): has next true
  01-06 13:30:32.827: I/DataService(1819): inactive
  01-06 13:30:32.837: I/DataService(1819): has next true
  01-06 13:30:32.837: I/DataService(1819): _timeCreated
  01-06 13:30:32.837: I/DataService(1819): has next true
  01-06 13:30:32.837: I/DataService(1819): 2014-04-14 14:44:49
  01-06 13:30:32.837: I/DataService(1819): has next true
  01-06 13:30:32.837: I/DataService(1819): _timeChanged
  01-06 13:30:32.837: I/DataService(1819): has next true
  01-06 13:30:32.837: I/DataService(1819): 2014-08-08 12:30:20
  01-06 13:30:32.837: I/DataService(1819): has next false

所以,它到达第一个对象的"_timeChanged":"2014-08-08 12:30:20",然后reader.hasNext() 变成false,而不是移动到新的BEGIN_OBJECT 令牌。

我错过了什么? TIA

【问题讨论】:

我在 GSON 识别 json 中的(非 json)数组时遇到了问题,即方括号数组。我发现我必须为包含 MyClass[] 数组类的 json api 响应创建一个类。这可能是问题吗? 为什么[] 数组不是json? 我在一些不使用方括号的项目中看到了另一种在 json 中构造数组数据的方法。我一直把它称为 json 数组和方括号数组,我只是称之为数组。看起来可能只有我才能做出这种区分。为了让我的答案更清楚,我说得不太清楚,抱歉。 【参考方案1】:

hasNext() 表示“如果当前数组或对象有另一个元素,则返回 true。”在您的情况下,当它到达对象或数组的末尾时 hasNext()false 所以 case END_ARRAYcase END_OBJECT 不要被调用。

这可能有效:

while( reader.hasNext() 
        || reader.peek() == END_ARRAY 
        || reader.peek() == END_OBJECT )
    eachToken( reader );
    Log.i( TAG, "has next " + reader.hasNext() );

这与乔伊的回答基本相同,但不适合发表评论。

【讨论】:

【参考方案2】:

我猜问题可能在于您处理数据的方式

如果您查看JavaDoc 的JsonReader,它特别定义了您需要使用数组括号..

在数组处理方法中,首先调用 beginArray() 以使用数组的左括号。然后创建一个累积值的 while 循环,当 hasNext() 为 false 时终止。最后,通过调用 endArray() 读取数组的右括号。

所以数组完成后hasNext()为假...

【讨论】:

嗯,我已经在数组的第一个元素的末尾得到hasNext() == false,在数组完成之前...

以上是关于GSON:END_OBJECT 永远不会被调用的主要内容,如果未能解决你的问题,请参考以下文章

S3.putObject - 回调永远不会被调用

QAbstractItemModel data() 永远不会被调用

Hibernate @PostLoad 永远不会被调用

Android onSystemUiVisibilityChange 永远不会被调用

SSE:“onmessage”永远不会被调用

意图服务永远不会被调用