2012-04-18 51 views
0

我有一个JSON文件(towns.json)坐在我的服务器上,在我的应用程序中,我希望从那里读取数据。 所以我想通了,我应该使用AsyncTask不阻止UI线程。我这样做如下:Android:在AsyncTask中发布JSON

private class GetTowns extends AsyncTask<String, String, Void> { 
    protected void onPreExecute() {} 

    @Override 
    protected Void doInBackground(String... params) { 
     String readTown = readFeed(ScreenStart.this, "http://server.com/towns.json"); 
     try { 
      JSONArray jsonArray = new JSONArray(readTown); 
      town = new ObjectTown[jsonArray.length()]; 
      for (int i = 0; i < jsonArray.length(); i++) { 
       JSONObject jsonObject = jsonArray.getJSONObject(i); 
       town[i] = new ObjectTown(); 
       town[i].setId(Integer.parseInt(jsonObject.getString("id"))); 
       town[i].setName(jsonObject.getString("name")); 
       town[i].setLat(Double.parseDouble(jsonObject.getString("latitude"))); 
       town[i].setLon(Double.parseDouble(jsonObject.getString("longitude"))); 
      } 
     } catch (Exception e) { 
      Log.i("Catch the exception", e + ""); 
     } 
     return null; 
    } 

    protected void onPostExecute(Void v) {} 
} 

而且readFeed()函数在这里:

public static String readFeed(Context context, String str) { 
    StringBuilder builder = new StringBuilder(); 
    HttpClient client = new DefaultHttpClient(); 
    HttpGet httpGet = new HttpGet(str); 

    try { 
     HttpResponse response = client.execute(httpGet); 

     StatusLine statusLine = response.getStatusLine(); 
     int statusCode = statusLine.getStatusCode(); 
     if (statusCode == 200) { 
      HttpEntity entity = response.getEntity(); 
      InputStream content = entity.getContent(); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(content, "ISO-8859-1")); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       builder.append(line); 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return builder.toString(); 
} 

它的工作原理有时 ...但过一段时间,在doInBackground()抛出此异常:

org.json.JSONException:在字符的输入0结束......

我究竟做错了什么?

回答

1

它看起来像服务器没有返回数据,你检查它,你的字符串是非空?要打开HttpEntity成字符串你可以使用:

String jsonStr = EntityUtils.toString(httpEntity); 

我想你也应该检查,如果实体是使用它之前null不同。

+0

问题是,它只有_sometimes_抛出这个错误! (服务器上的文件始终可用)。 – user934779 2012-04-18 16:01:29

+1

当错误发生时检查了readTown内容吗? – marcinj 2012-04-18 16:29:23

+0

有时候,readTown的内容不会返回结果。这是问题。 – user934779 2012-04-18 17:33:38

1

使用AsyncTasks发送REST请求并不是一个好主意。 AsyncTasks不应该用于网络等长时间运行的操作。事实上的AsyncTask有涉及两个主要问题:

  • 他们不好绑在活动的生命周期
  • 将导致内存泄漏很容易。

里面的RoboSpice动机应用程序(available on Google Play)我们给AsyncTasks的深度来看,装载机,它们的特点和缺点,当涉及到网络,也给你介绍一个替代解决方案:RoboSpice。

我们甚至提供了an infographics来解释这个问题。把它用几句话

  • AsyncTasks是有缺陷的,因为它们不好绑到活动的生命周期和内存泄漏的
  • 装载机是什么,他们已经设计了相当不错的:SQLite数据库的访问游标,但不要为网络提供任何支持。他们是这个错误的工具。
  • RoboSpice在服务中执行网络请求,您的下载在Android服务中执行,内存管理良好,甚至为编写REST请求提供支持。

我鼓励你下载RoboSpice Motivations app,它确实说明对此进行了深入,并提供样品和方式的不同做一些后台操作演示。