2

私は解決された問題であると感じるものを持っています。私が書いているAndroidアプリケーションは、ユーザーがファイルを添付できるSMSのようなメッセージを送信します。私はHttpUrlConnectionを使用して、このデータをサーバーに送信しています。サーバーは、基本的にjava.io.OutputStreamにまとめられています(DataOutputStreamでラップしています)。

モバイルデバイスを使用している場合、ネットワーク接続がまったくひどい場合があり、送信に時​​間がかかりすぎる場合があります。私には次の2つの基本的な問題があります。

  1. ユーザーにはアップロードの進行状況を知る方法がありません
  2. ネットワークがひどく進行がひどい場合-そこに座って5〜10分間試すのではなく、単に中止するか、ある程度のタイムアウトを設定したいと思います。

問題1:

4Kバッファーで行っているoutputstreamwrite()呼び出しに基づいて、アップロードの進行状況を表示しようとしました。

        buffer = new byte[4096];
        long totalBytes = 0;
        while ((bytesRead = fis.read(buffer)) > -1) {
            totalBytes += bytesRead;
            dos.write(buffer, 0, bytesRead);
            if(showProgress){
               updateProgressBar(totalBytes);
            }
        }

これは進行状況を示していますが、アプリがファイルバッファーをOSネットワークスタックバッファーに転送できる速度を示しているようです。プログレスバーは、低速のネットワークでも非常に速く終了し、その後、サーバーからJSONを取得して送信のステータスを通知する前に、さらに長時間そこに留まります。確かに、それをOSに渡してから、サーバーがそれを受け取ったと通知するまで、ある程度の進歩を遂げる方法はありますか?

問題2:

ネットワーク接続が悪い場合もありますが、ハードウェア無線が接続が見つからない場合にコールバックをトリガーするほど悪くはありません(この場合、オフラインモードになります)。ですから、それが悪いのにオフではないとき、私のアプリは牛が家に帰るまで送信ダイアログに座っているだけです。これは、OutputStreamがネイティブにタイムアウトメカニズムを提供しないため、実際のスループットを何らかの形で認識する必要があるという点で、問題1に関連しています。それがしきい値を下回った場合、接続をキャンセルして、適切な受信でどこかに行く必要があることをユーザーに通知することができます。

補足:非同期送信/出力キューは、メッセージをディスクに永続化できないため、オプションではありません。したがって、後で送信に失敗した場合に、ドラフトされたメッセージが無期限に送信されることを保証できません。送信をブロックする必要がある/ブロックしたいのですが、あきらめたり、何が起こっているのかをユーザーに通知したりすることについて、より賢くする必要があります。

4

1 に答える 1

1

アプリがファイルバッファをOSネットワークスタックバッファに転送できる速度を示しているようです。

それより悪いです。HttpURLConnectionこれは、アプリが書き込み中の内部にデータを転送できる速度を示します。ByteArrayOutputStreamこれにより、コンテンツを書き込む前に、コンテンツの長さを確認し、ヘッダーを設定できます。

幸いなことに、それよりも優れています。データの長さが事前にわかっている場合は、固定長転送モードを設定してください。そうでない場合は、1024のような低いチャンクサイズでチャンク転送モードを設定します。

次に、アプリケーションがデータをソケット送信バッファーに移動する速度がわかります。チャンク転送モードの場合、チャンクサイズの単位。ただし、ソケット送信バッファーがいっぱいになると、書き込みはブロックされ、少なくとも最後の書き込みが完了するまで、実際のネットワーク転送が表示されます。その時点から書き込みと終了はどちらも非同期であるため、表示は早くポップアップしますが、誰もがその問題を抱えています。

問題2に関しては、転送が上記のようにネットワーク速度に落ち着いたら、独自のスループットを計算し、それが不十分な場合はそれに応じて対応できます。

于 2013-02-22T00:27:59.727 に答える