2017-09-27 1 views
0

を通じてJSONにオブジェクトを変換するとき、私はGsonを使用してJSONにオブジェクトのリストを変換するときに私は(常にではない)一部のユーザーのためのにOutOfMemory例外Gson

java.lang.OutOfMemoryErrorを

を取得しています。それを修正する方法を教えてください。

@Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     if(myList != null && !myList.isEmpty()) { 
      //exception at this line 
      String myJson = new Gson().toJson(myList, myList.getClass()); 
      outState.putString(MY_LIST, myJson); 
     } 
     outState.putInt(NEXT_PAGE, getNextPage()); 
    } 

はmyListは私のカスタムオブジェクトとリストのサイズのリストは、これはあなたのリストのサイズに依存します600キロバイト

+0

そのmyListのサイズを確認してください – Stultuske

+0

@Stultuskeサイズが大きいです。しかし、私は大きなサイズのリストを変換する必要があります。何か方法はありますか? –

+0

'myList'は正規リストですか? 'myList'に含まれるオブジェクトのクラスは何ですか? – Haem

答えて

1

〜400キロバイトです。あなたは

public String writeListToJson(List myList) throws IOException { 
    ByteArrayOutputStream byteStream =new ByteArrayOutputStream(); 
    OutputStreamWriter outputStreamWriter=new OutputStreamWriter(byteStream ,"UTF-8"); 
    JsonWriter writer = new JsonWriter(outputStreamWriter); 
    writer.setIndent(" "); 
    writer.beginArray(); 
    Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().setPrettyPrinting().create(); 
    for (Object o : myList) { 
     gson.toJson(o, o.class, writer); 
    } 
    writer.endArray(); 
    writer.close(); 
    return byteStream.toString("UTF-8"); 
} 
+0

なぜ最終的な結果を 'String'に変換する場合に' JsonWriter'をストリーミングするのですか? – pskink

+0

@pskinkもしあなたがOPを見たら、彼はoutStateの "outState.putString(MY_LIST、myJson);に"文字列 "を書き戻しています;それは大きなリストをgsonに変換していないのでgsonのヘルパーです。だから彼はこのutilクラスを使うことができ、Gsonから過去のOOMを取得し、それを望むように文字列を使うことができます。 – Optional

+0

あなたのメソッドでは、1)大きな 'myList' 2)' myList'コンテンツを格納しなければならない2)大きな 'ByteArrayOutputStream'と、3)' byteStream.toString'の結果として大きな 'String'があります。大きなデータオブジェクトは 'OOM'例外の場合に役立ちますか? – pskink

1

はmyListがリストの私のカスタムオブジェクトとサイズのリストは、600キロバイト

〜400キロバイトですのようなもの、より具体的には、ストリーミングAPI https://sites.google.com/site/gson/streaming

を使用していないのはなぜにすると、保存されたインスタンスの状態Bundleになります。 OutOfMemoryErrorはあなたの心配の1つに過ぎません。多くの場合、FAILED BINDER TRANSACTIONでクラッシュします。これは、アプリで同時に実行されるすべてのIPCトランザクションに1MBの制限があるためです。

設定の変更に対処しようとしている場合、この情報に保持するために何か他のものを使用します。

  • Androidのアーキテクチャのコンポーネントから保持フラグメント
  • onRetainNonConfigurationInstance()
  • ViewModel
  • など

プロセスを処理しようとしている場合終了/アプリケーションを再起動するには、保存されたインスタンス状態Bundleに識別子を入れてください。このリストは、永続ストア(データベース、プレーンファイルなど)からこのリストを再ロードできます。

関連する問題