4

以下のコードを使用して、Web から取得した JSON 文字列 (30,000 レコード) を解析しています。

DefaultHttpClient   httpclient = new DefaultHttpClient(new BasicHttpParams());
        HttpPost httppost = new HttpPost(params[0]);
        httppost.setHeader("Content-type", "application/json");
        InputStream inputStream = null;
        String result = null;
        HttpResponse response = null;
        try {
            response = httpclient.execute(httppost);

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }           
        HttpEntity entity = response.getEntity();
        try {
            inputStream = entity.getContent();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"),8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null)  
            {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        result = sb.toString();

以下のコードで OutofMemory エラーが発生しています

while ((line = reader.readLine()) != null)  
{
    sb.append(line + "\n");
}

このエラーを取り除く方法. このエラーは、json 文字列が約 30,000 レコードのデータを含んでいるため、非常に巨大な場合に発生します。

この点でどんな助けでも大歓迎です..

4

4 に答える 4

3

Android では、アプリケーションごとにメモリ上限 (ほとんどすべての携帯電話で 16 MB、一部の新しいタブレットではそれ以上) が課されています。アプリケーションは、ライブ メモリの制限をそのレベル未満に維持する必要があります。

そのため、アプリケーションの合計ライブ メモリ使用量がその制限を超える可能性があるため、1MB を超えるような大きな文字列を完全に保持することはできません。合計メモリ使用量には、アプリで割り当てたすべてのオブジェクト (UI 要素を含む) が含まれることを思い出してください。

したがって、唯一の解決策は、データをそのまま受け取るストリーミング JSON パーサーを使用することです。つまり、String オブジェクトで完全な文字列を保持するべきではありません。1 つのオプションは、Jackson JSON パーサーを使用することです。

編集: Android はAPI レベル 11 からJSONReaderをサポートするようになりました。

于 2012-11-01T11:45:55.410 に答える
1

データ ファイルが大きすぎると、すべてをメモリに読み込むことができません。

行を読み取り、それをネイティブ ファイルに書き込みます。すべてのデータをメモリに保持するために StringBuilder を使用しないでください。

于 2012-11-01T11:43:33.953 に答える
0

このライブラリでこの問題を解決しました。ここには非常に優れたチュートリアルがあります

これにより、entity.getContent() を String に変換することをバイパスし、問題を解決します。

InputStream inputStream = entity.getContent();
JsonReader reader = Json.createReader(inputStream);
JsonObject jsonObject = reader.readObject();
return jsonObject;
于 2014-09-02T09:18:55.957 に答える
0

毎回 1000 レコードなど、チャンクでデータをインポートしてみてください。この問題が発生しないことを願っています。

于 2012-11-01T11:45:17.267 に答える