ホーム>source

20 MB前後の大きなJSONデータがあります( JSON.stringify を使用してこのデータを作成します    JavaScriptコードから)。このJSONデータをAndroidデバイスの内部ストレージファイルに書き込み、後で読み取ります。そのため、ファイルを読むのに時間がかかりすぎて、そのファイルを読んでいるかどうかはわかりません。もう1つ、メインスレッドでのみ読む必要があります。

WriteFile にデータ値「Hello World」を渡すと、以下のコードは正常に動作します  メソッド、しかし、それは大きなJSONで失敗します

public String ReadFile()
{
    StringBuffer text = new StringBuffer();
    String FILE_NAME = "file.txt";
    try {
        BufferedReader bReader = new BufferedReader(new InputStreamReader(openFileInput(FILE_NAME)));
        String line;
        int count = 0;
        while ((line = bReader.readLine()) != null) {
            text.append(line + "\n");
            alert("Reading File: " + ++count);
        }
    } 
    catch (Exception e) {
        alert(e.toString());
    }
    return text.toString();
}
public String WriteFile(String data)
{
    String FILE_NAME = "file.txt";
    String result = "";
  try {
      FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
      fos.write(data.toString().getBytes());
      result = "Success";
      fos.close();
    }
    catch (Exception e) {
        e.printStackTrace();
        result="Error";
   }
    return result;
}

loop の間に1つのアラートを追加しました  また、ただし、アラートメッセージは表示されません。 Exception も見たことがありません  メッセージも。

したがって、2つの問題が発生する可能性があります。

  1. ファイルへの書き込みに問題があります(ただし、内部ストレージファイルを表示する方法がないと思うため、これを確認する方法がわかりません)。

  2. 読み取りコードに問題があります。

アップデート1:

Javaネイティブコードで非常に大きなファイルを読み取ることができない場合、WebView JavaScriptコードから内部ストレージAndroidファイルを読み取る方法はありますか?

================================================== ==========================

アプリケーション要件

WebViewがあるAndroidアプリケーションがあります。完全なJavaScriptコード(jsおよびHTMLファイル)をアプリのアセットフォルダーにコピーしました。 Javaネイティブコードからファイルに書き込み、Javaネイティブコードから読み取ります。アプリの起動時にサーバーからすべてのデータを取得しています。クライアントのインターネット接続が非常に遅く、何度も切断されます。そのため、彼らはこのアプリをオフラインモードで実行することを望んでいます。平均値アプリは起動時にすべてのデータを取得し、どこかに保存してからアプリ全体で読み取ります。ユーザーがアプリを再度起動すると、古い既存のデータが取得されます。実際、このデータは非常に大きいため、内部ストレージファイルに保存しています。

あなたの答え
  • 解決した方法 # 1

    まず、コードに時間がかかっている理由を本当に確認する唯一の方法は、プロファイルを作成することです。私たちはあなたのためにそれを行うことはできません。

    ただし、コードに関連するパフォーマンスのヒントは次のとおりです。

    本当に必要な場合を除き、20MBのJSONファイル全体をJavaヒープ/ RAMメモリに読み込まないでください。 (私はあなたがこれをしている理由を理解するのが難しいと感じています。例えば、典型的なJSONパーサーは喜んで1 ファイルから直接入力を読み取ります。または、これを読んでHTTP接続の相手側のクライアントに送信できるようにするには、データをストリーミングできる必要があります。)

    ファイルを一度に1行ずつ読み取り、それらの行をつなぎ合わせる必要はありません。不要なゴミを生成します。余分なガベージは、GCの処理量が増えることを意味し、速度が低下します。行が長い場合、内部 StringBuilder を使用することでパフォーマンスが向上します。  各行を作成します。

    リサイクル char[] を読む 、次に char[] を追加します   StringBuilder へのコンテンツ  行を追加するよりも高速になります。

    あなたの StringBuilder  追加する文字を収容するために、補助文字配列を繰り返し「成長」させます。これはゴミを生成し、不必要なコピーにつながります。 (通常、実装は O(N^2) を避けるために配列を指数関数的に「成長」させます  動作。ただし、拡張は依然としてパフォーマンスに影響を与え、実際に必要なメモリ使用量の最大3倍のピークメモリ使用量になる可能性があります。

    これを回避する1つの方法は、 StringBuilder を追加して設定する文字数の初期推定値を取得することです  それに応じて「容量」。ファイルサイズから文字数を推定できる場合があります。 (エンコードに依存します。)

    既存の標準Javaライブラリを使用してそれを行う方法を探します。例えば Files.copy  および ByteArrayOutputStream 、または Files.readAllBytes

    既存のサードパーティライブラリメソッドを探します。例えばApache Commons IOには IOUtils.toString(Reader) があります  方法。チャンスは彼ら これを行う方法を見つけるのに多くの時間を費やしていたでしょう効率的に。適切に設計され、適切に管理されたライブラリを再利用すると、時間を節約できる可能性があります。

    トレースプリントを入れないでください(それが alert  ...)何百万回と呼ばれる可能性のあるループの途中で。 (だよ!)


    1-パーサーは、それらを知ると元気になります:-)

関連記事

  • 前へ java - JPAクエリ:サブクエリをグループ化条件に結合する
  • 次へ BashでのPythonシェルの使用