使用执行程序服务从 url 下载

download from url with executor service

我在执行程序服务中使用下面的代码从 URL 下载文件。它下载文件但大小为 0 字节。当我使用 asyncTask 时代码工作正常。但是当我把它放在执行程序服务中时不起作用。

下载无法完成的任何想法?

创建时:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ExecutorService pool = Executors.newSingleThreadExecutor();
        Button btn = findViewById(R.id.btn);
        String url = "https://file-examples-com.github.io/uploads/2017/10/file_example_JPG_100kB.jpg";
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                pool.execute(new NetworkService(url));

            }
        });

网络服务class:

private class NetworkService implements Runnable {
        private String url;

        public NetworkService(String url) {
            this.url = url;
        }

        @Override
        public void run() {
            dlFile(url);
        }

        private String dlFile(String surl) {

            try {
                InputStream input = null;
                OutputStream output = null;
                HttpURLConnection connection = null;
                try {
                    URL url = new URL(surl);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.connect();
                    if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
                        return "Server returned HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage();
                    input = connection.getInputStream();
                    String title = URLUtil.guessFileName(String.valueOf(url), null, null);
                    output = new FileOutputStream(Environment.getExternalStorageDirectory().toString()  + "/" + title);

                } catch (Exception e) {
                    return e.toString();
                } finally {
                    try {
                        if (output != null)
                            output.close();
                        if (input != null)
                            input.close();
                    } catch (IOException ignored) {
                    }
                    if (connection != null)
                        connection.disconnect();
                }
            } finally {
            }
            return  null;
        }
    }

有几件事你应该做并验证。

1 - 首先,确保您已授予将文件保存到存储器所需的权限。

  • READ_EXTERNAL_STORAGE
  • WRITE_EXTERNAL_STORAGE
  • INTERNET

2 - 将 android:requestLegacyExternalStorage="true" 添加到 android 10 及更高版本的清单文件的应用程序标签中。

3 - 更正您的 FileOutputStream 初始化,因为

val direct = File(Environment.getExternalStorageDirectory().toString() + "/test_files")

您正在 test_files 文件夹中创建上面的路径,但在 FileOutputStream 中您指定了不同的路径。所以,正确的行应该是

output = FileOutputStream( direct + "/" + title)

最后,在 output = 行之后添加以下行以将图像写入缓冲区,因为您正在读取 InputStream 而不是将其写入缓冲区。这就是为什么它只在存储中创建路径,但不将文件写入该路径。

val buf = ByteArray(1024)
var len: Int
while (input.read(buf).also { len = it } > 0) {
      output.write(buf, 0, len)
}

PS: 我用 Kotlin 写了代码并在 Android 10 上测试过,它工作正常.

希望对您有所帮助。如果对您有帮助,请不要忘记采纳。