0

サーバーにJSONファイル(towns.json)があり、アプリでそこからデータを読み取りたいと思っています。そのため、UIスレッドをブロックしないようにAsyncTaskを使用する必要があることがわかりました。私はそれを次のようにやっています:

    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で入力が終了します。

私は正確に何を間違っているのですか?

4

2 に答える 2

1

サーバーがデータを返さないようです。文字列が空でないことを確認しましたか?HttpEntityを文字列に変換するには、次を使用できます。

String jsonStr = EntityUtils.toString(httpEntity);

エンティティを使用する前に、エンティティがnullと異なるかどうかも確認する必要があると思います。

于 2012-04-18T15:34:59.397 に答える
1

AsyncTasksを使用してRESTリクエストを送信することはお勧めできません。AsyncTasksは、ネットワーキングなどの長時間実行される操作には使用しないでください。実際、AsyncTaskには関連する2つの主要な問題があります。

  • それらは活動のライフサイクルとの結びつきが不十分です
  • 作成メモリリークは非常に簡単です。

RoboSpice Motivationsアプリ(Google Playで入手可能)の内部では、AsyncTasks、ローダー、ネットワークに関する機能と欠点の詳細を示し、代替ソリューションであるRoboSpiceを紹介します。

この問題を説明するためのインフォグラフィックも提供しました。一言で言えば

  • AsyncTasksは、アクティビティライフサイクルとの関連付けが不十分であり、メモリリークが発生するため、欠陥があります。
  • ローダーは、Sqliteデータベースのカーソルにアクセスするために設計されたものにはかなり適していますが、ネットワーキングのサポートは提供していません。これらはこれには間違ったツールです。
  • RoboSpiceはサービスでネットワークリクエストを実行し、ダウンロードはAndroidサービスで実行され、メモリは適切に管理され、RESTリクエストの書き込みもサポートします。

RoboSpice Motivationsアプリをダウンロードすることをお勧めします。これは、この詳細を実際に説明し、いくつかのバックグラウンド操作を行うためのさまざまな方法のサンプルとデモンストレーションを提供します。

于 2012-10-26T07:00:05.387 に答える