2012-04-18 4 views
0

내 서버에 JSON 파일 (towns.json)이 있고 앱에서 데이터를 읽으 려합니다. 그래서 UI 스레드를 차단하지 않기 위해 AsyncTask를 사용해야한다고 생각했습니다.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()이 예외를 throw :

org.json.JSONException : 문자의 0 입력의 끝 ... 정확히 내가 잘못

을 뭐하는 거지?

답변

1

서버가 데이터를 반환하지 않는 것 같습니다. 문자열을 비어 있지 않은지 확인 했습니까? HttpEntity를 문자열로 바꾸려면 다음을 사용할 수 있습니다.

String jsonStr = EntityUtils.toString(httpEntity); 

엔티티가 사용하기 전에 null인지 확인해야한다고 가정합니다.

+0

문제는 _sometimes_가이 오류를 throw합니다. (서버의 파일은 항상 사용 가능합니다). – user934779

+1

오류가 발생하면 readTown 내용을 확인 했습니까? – marcinj

+0

때때로 readTown의 내용이 결과를 반환하지 않습니다. 그것이 문제였습니다. – user934779

1

AsyncTasks를 사용하여 REST 요청을 보내는 것은 좋지 않습니다. 네트워킹과 같은 장기 실행 작업에는 AsyncTasks를 사용하지 않아야합니다.

  • 그들은 가난 메모리 누수를 만드는 아주 쉽게 활동 수명주기
  • 에 연결되어 : 사실 AsyncTask를 관련된 두 가지 문제가 있습니다. RoboSpice을 다음 RoboSpice 동기 부여 응용 프로그램 (available on Google Play) 우리가 AsyncTasks에 대한 심층적 인 뷰를 제공 내부

로더, 자신의 기능과 단점은 네트워킹 또한 대체 솔루션을 소개 할 때.

우리는이 문제를 설명하기 위해 an infographics도 제공했습니다. 그들은 제대로 활동 라이프 사이클에 연결된 메모리를 만들 수 있습니다으로

  • AsyncTasks가 결함이 몇 마디에 넣어하려면
  • 로더들이 위해 설계 한 것에 대해 꽤 좋은 누수 : SQLite 데이터베이스의 접근 커서하지만, 네트워킹에 대한 지원을 제공하지 마십시오. 이것들은 잘못된 도구입니다.
  • RoboSpice는 서비스에서 네트워크 요청을 실행하고 다운로드는 Android 서비스에서 실행되며 메모리는 잘 관리되며 REST 요청 작성을 지원합니다.

내가 RoboSpice Motivations app를 다운로드하는 것이 좋습니다, 그것은 정말 깊이있는 설명과 샘플 및 몇 가지 배경 작업을 할 수있는 다른 방법의 데모를 제공합니다.