私は解決された問題であると感じるものを持っています。私が書いているAndroidアプリケーションは、ユーザーがファイルを添付できるSMSのようなメッセージを送信します。私はHttpUrlConnectionを使用して、このデータをサーバーに送信しています。サーバーは、基本的にjava.io.OutputStreamにまとめられています(DataOutputStreamでラップしています)。
モバイルデバイスを使用している場合、ネットワーク接続がまったくひどい場合があり、送信に時間がかかりすぎる場合があります。私には次の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に関連しています。それがしきい値を下回った場合、接続をキャンセルして、適切な受信でどこかに行く必要があることをユーザーに通知することができます。
補足:非同期送信/出力キューは、メッセージをディスクに永続化できないため、オプションではありません。したがって、後で送信に失敗した場合に、ドラフトされたメッセージが無期限に送信されることを保証できません。送信をブロックする必要がある/ブロックしたいのですが、あきらめたり、何が起こっているのかをユーザーに通知したりすることについて、より賢くする必要があります。