xamarin.androidアプリでは、リモートサーバーからファイルをダウンロードしており、クライアントリストの行項目が進行状況に更新されます。ファイルをPCLからXamarin.Androidに更新する
これはアンドロイドとiosに共通のダウンロードを行うためのpclを作成したものです。私たちは以下のようにリモートサーバーからファイルをダウンロードするためには、HttpWebRequestを求めている新しいワーカースレッドからxamarin.androidアプリから
、
ThreadStart downloadThreadStart = new ThreadStart(() =>
{
Stream destinationFileStream = FileUtils.GetFileStream(fileName, info, context);
// Call the static method downloadFile present in PCL library class WebRequestHandler
WebRequestHandler.downloadFile(listener, fileName, key, destinationFileStream);
});
new Thread(downloadThreadStart).Start();
PCLからダウンロードした後、私たちは/のawait使用してライト・ファイルの内容メソッドを呼び出しています非同期。
await WriteFileContentAsync(response.GetResponseStream(), destFileStream,
Convert.ToInt64(size), listener, geoidFileName);
HttpWebResponseの入力ストリームを読み取って内部記憶装置に存在する出力ストリームファイルにデータを書き込むために使用される以下のコードスニペット。私たちは以下のようにUIスレッドで実行内のUIを更新しているコールバックがxamarin.androidに受信されると
private static async Task WriteFileContentAsync(Stream sourceStream,
Stream destFileStream, long size, ResponseListener listener, string filename)
{
byte[] buffer = new byte[BUFFER_SIZE];
//Interface callback sent to the xamarin.android application
listener.UpdateDownloadProgress(filename, 0);
try
{
int currentIndex = 0;
int bytesRead = await sourceStream.ReadAsync(buffer,
0, buffer.Length);
while (bytesRead > 0)
{
await destFileStream.WriteAsync(buffer, 0, bytesRead);
currentIndex += bytesRead;
int percentage = (int)(((double)currentIndex/size) * 100);
Debug.WriteLine("Progress value is : " + percentage);
listener.UpdateDownloadProgress(filename, percentage);
bytesRead = await sourceStream.ReadAsync(buffer,
0, buffer.Length);
}
listener.UpdateDownloadProgress(filename, 100);
//Send the callback
listener.updateDownloadStatus(ResponseStatus.Success, filename);
}
catch (Exception ex)
{
Debug.WriteLine("Geoid file write exception : " + ex);
listener.updateDownloadStatus(ResponseStatus.Error, filename);
}
finally
{
if (sourceStream != null)
{
sourceStream.Flush();
sourceStream.Dispose();
}
if (destFileStream != null)
{
destFileStream.Flush();
destFileStream.Dispose();
}
}
}
、
public void UpdateDownloadProgress(string filename, int progressValue)
{
//Skip the progress update if the current and previous progress value is same
if (previousProgressValue == progressValue)
{
return;
}
int position = findAndUpdateProgressInList(filename);
this.itemList[position].ProgressValue = progressValue;
RunOnUiThread(() =>
{
this.coordinateAdapter.NotifyDataSetChanged();
});
}
しかし、アプリが突然クラッシュして閉じます。ダウンロード中はすぐにアプリが突然終了し、クラッシュするとすぐにステータスが更新されます。スクロールも滑らかではありません。
スレッドからダウンロードするAPIを呼び出しています。 Xamarinの "Report download progress"参照リンクを読むと、待機/非同期の内部呼び出しがバックグラウンドタスクを実行するためにスレッドプールを使用することが示されます。
スレッドなしで試してみると、ダウンロードアイコンを押すとUIがハングアップします。スレッド内で呼び出すとUIが応答し、すぐにクラッシュします。
PCL非同期/ Xamarin android UI通信を待つことが適切ではありません。
この問題を解決するために私を助けてください。