Я реализую менеджер загрузок на родном android, где для реализации параллельных загрузок используется исполнитель пула потоков.Runnable - это место, где происходит фактическая загрузка, которая выполняется в потоках пула.Как я могу отправить прогресс загрузки из runnable в пользовательский интерфейс?Для того, чтобы отправлять трансляции, мне нужно передать контекст в runnable.Это подходящий способ?
Как можно изящно обработать паузу / возобновление / отмену загрузки?Прямо сейчас, когда пользователь нажимает кнопку паузы / отмены, значение обновляется в БД, и пока условие Thread.CurrentThread (). IsInterrupted в исполняемом файле становится действительным, я проверяю состояние в базе данных и решаю, нужно ли мне удалить частично загруженный файл.файл (если его отменить).
Кроме того, можно ли будет узнать, когда загрузка завершится, чтобы я мог удалить будущий объект из списка?
public class Downloadable : Java.Lang.Object, IRunnable
{
private readonly string _destination;
private readonly int _productId;
public Downloadable(int productId)
{
_productId = productId;
_destination = Utils.StoragePath() + productId + ".zip";
}
public void Run()
{
int count;
try
{
Response response = CloudService.GetCloud().GetDownLoadURL(_productId.ToString(), true).Result;
if (string.Equals(response.status, "error", StringComparison.OrdinalIgnoreCase) || string.Equals(response.status, "internalError", StringComparison.OrdinalIgnoreCase))
{
//send error
}
else
{
DownloadPath downloadPath = JsonConvert.DeserializeObject<DownloadPath>(response.data);
string offlineUrl = downloadPath.contentUrl.Offline;
if (string.IsNullOrWhiteSpace(offlineUrl))
{
//send error
}
else
{
File directory = new File(Utils.StoragePath());
if (!directory.Exists())
directory.Mkdirs();
URL url = new URL(offlineUrl);
HttpURLConnection connection = (HttpURLConnection)url.OpenConnection();
long total = 0;
File file = new File(_destination);
file.CreateNewFile();
if (file.Exists() && file.Length() > 0)
{
total = file.Length();
connection.SetRequestProperty("Range", "Bytes=" + total + "-");
}
connection.Connect();
int lenghtOfFile = connection.ContentLength;
BufferedInputStream bufferedInputStream = new BufferedInputStream(url.OpenStream());
FileOutputStream fileOutputStream = new FileOutputStream(_destination, true);
byte[] buffer = new byte[1024];
count = 0;
while ((count = bufferedInputStream.Read(buffer, 0, 1024)) != -1)
{
if (Thread.CurrentThread().IsInterrupted)
{
if (DBService.GetDB().GetStatus(_productId) == (int)IpcCommon.Enumerations.Status.DOWNLOAD)
file.Delete();
break;
}
total += count;
System.Console.WriteLine("__PROGRESS__ " + (int)((total * 100) / lenghtOfFile));
System.Console.WriteLine("__PROGRESS__ ID " + _productId);
//publishProgress("" + (int)((total * 100) / lenghtOfFile));
fileOutputStream.Write(buffer, 0, count);
}
fileOutputStream.Close();
bufferedInputStream.Close();
}
}
}
catch (System.Exception exception)
{
IpcCommon.App.Logger.Log("Downloadable - File Download", new System.Collections.Generic.Dictionary<string, string> { { "Error", exception.Message } });
}
}
}
Dictionary<int, IFuture> _runningTaskList = new Dictionary<int, IFuture>();
int noOfCores = Runtime.GetRuntime().AvailableProcessors();
LinkedBlockingQueue _taskQueue = new LinkedBlockingQueue();
_threadPoolExecutor = new ThreadPoolExecutor(noOfCores, noOfCores * 2, 1, TimeUnit.Minutes, _taskQueue);
IFuture future = _threadPoolExecutor.Submit(new Downloadable(productId));
_runningTaskList.Add(productId, future);