【问题标题】:How to download files without making application GUI freeze如何在不冻结应用程序 GUI 的情况下下载文件
【发布时间】:2013-09-29 07:38:13
【问题描述】:

我正在创建一个从 URL(我自己的 FTP 服务器)下载文件的应用程序。问题是,当我点击“下载”按钮时,我的应用程序将开始下载,但我的应用程序在下载时没有任何响应,但下载后一切正常。

这是我的代码的一部分

GUI.class

b_Download.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                       String username = "Test";
                       startDownloading(username);
            }   
        });

private void startDownload(String username)
    {
        downloader.println("Welcome " + username); //println will show text in a textpane(GUI) and console
        downloader.startDownloading();
    }

Downloader.class

public void startDownloading()
{       
                println("Download jobs started");


                download.downloadLIB();    
}

下载Job.class

public void downloadLIB()
    {
        launcher.println("Start downloading files from server...");
        String libURL = "http://www.example.com/file.jar";
        File libFile = new File("C://file.jar");
        downloadFile(libURL, libFile, "file.jar");
    }
public void downloadFile(String url, File path, String fileName)
    {
        InputStream in = null;
        FileOutputStream fout = null;
        try
        {
            in = URI.create(url).toURL().openStream();
            fout = new FileOutputStream(path);

            byte data[] = new byte[1024];
            int count;
            while ((count = in.read(data, 0, 1024)) != -1)
            {
                fout.write(data, 0, count);
            }
        }
        catch(Exception e)
        {
            launcher.println("Cannot download file : " + fileName, e);
        }
        finally
        {
            if (in != null)
                try
                {
                    in.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            if(fout != null)
                try
                {
                    fout.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            launcher.println("File " + fileName + " downloaded successfully");
        }
    }

当我按下“下载”按钮时,我的文本窗格显示“欢迎用户名”这个词然后它没有响应。但是我的控制台会显示“欢迎用户名”、“开始下载作业”和“开始从服务器下载文件...”。几分钟后(文件下载完成后,我的应用程序将再次开始响应...

【问题讨论】:

标签: java swing download


【解决方案1】:

Swing 是一个单线程框架。也就是说,所有交互和修改都应该在 Event Dispatching Thread 的上下文中执行。

任何阻塞此线程的行为都会阻止它处理新事件,包括绘制请求。

这会让你陷入困境。执行下载而不是“冻结”程序的唯一方法是在某种后台线程中运行,但您不能从该线程更新或修改,因为这必须在 EDT 的上下文中完成。

虽然有多种方法可以解决此问题,但在您的情况下最简单的方法可能是使用SwingWorker

它能够在后台运行(脱离 EDT)、重新同步更新到 EDT 的方法(publishprocessdone),并提供用于报告进度的构建功能。

例如...

查看Concurrency in Swing了解更多详情...

【讨论】:

  • 所以你的意思是我必须使用 SwingWorker 并在后台进行下载进度?
  • 你能给我看一个在 Java 中使用 SwingWorker 的例子吗?因为我不熟悉
  • 我做到了。它们出现在我添加到问题末尾的三个链接中
【解决方案2】:

您需要生成一个新的Thread

当您向网络发送请求时,您会执行一段代码,该代码将挂起,直到它得到它正在寻找的东西,即服务器。这意味着您的应用程序主线程将有一段不会响应系统消息,导致系统认为它已停止响应。

解决方案是生成一个工作线程,或运行一个服务来处理您的网络请求。

线程在等待服务器时会挂起,而您的主活动线程可以继续与用户交互。

当工作线程完成其任务时,您需要回调主线程以提醒用户下载进度/完成。

【讨论】:

  • 喂!还是有关系的!哈哈!确实需要注意标签。 :D
猜你喜欢
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 2018-04-30
相关资源
最近更新 更多