Как обновить пользовательский интерфейс с прогрессом загрузки, когда загрузка выполняется в ThreadpoolExecutor? - PullRequest
1 голос
/ 02 мая 2019

Я реализую менеджер загрузок на родном 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);
...