欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > 【Android】安卓 Java下载ZIP文件并解压(笔记)

【Android】安卓 Java下载ZIP文件并解压(笔记)

2025/3/20 7:17:27 来源:https://blog.csdn.net/qq_41140324/article/details/146381224  浏览:    关键词:【Android】安卓 Java下载ZIP文件并解压(笔记)

写在前面的话

在这篇文章中,我们将详细讲解如何在 Android 中通过 Java 下载 ZIP 文件并解压,同时处理下载进度、错误处理以及优化方案。


以下正文


1.权限配置

在 AndroidManifest.xml 中,我们需要添加相应的权限来确保应用能够访问网络和设备存储。

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

⚠️ 注意:Android 10(API 29)及以上,建议使用 getExternalFilesDir() 来处理文件,而避免直接访问 /sdcard。

2.下载 ZIP 文件并保存到本地

文件下载

首先,我们需要编写下载 ZIP 文件的代码。这里使用 HttpURLConnection 来实现文件的下载,并保存到设备的存储中。

public void downloadZipFile(String urlStr, String savePath, DownloadCallback callback) {new Thread(() -> {InputStream input = null;FileOutputStream output = null;HttpURLConnection connection = null;try {URL url = new URL(urlStr);connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(10000);connection.setReadTimeout(10000);connection.connect();if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {callback.onFailed("Server returned HTTP " + connection.getResponseCode());return;}int fileLength = connection.getContentLength();input = connection.getInputStream();File file = new File(savePath);output = new FileOutputStream(file);byte[] buffer = new byte[4096];int bytesRead;long total = 0;while ((bytesRead = input.read(buffer)) != -1) {total += bytesRead;output.write(buffer, 0, bytesRead);int progress = (int) (total * 100 / fileLength);callback.onProgress(progress);}callback.onSuccess(file.getAbsolutePath());} catch (Exception e) {e.printStackTrace();callback.onFailed(e.getMessage());} finally {try {if (output != null) output.close();if (input != null) input.close();} catch (IOException ignored) {}if (connection != null) connection.disconnect();}}).start();
}

下载回调

为了处理下载过程中的进度、成功与失败,我们需要定义一个回调接口:

public interface DownloadCallback {void onProgress(int progress);  // 下载进度void onSuccess(String filePath); // 下载完成void onFailed(String error);     // 下载失败
}

3.解压 ZIP 文件’

文件解压

下载完成后,我们可以解压 ZIP 文件。Android 提供了 ZipInputStream 来处理解压工作。以下是解压代码实现:

public void unzip(String zipFilePath, String targetDirectory, UnzipCallback callback) {new Thread(() -> {try {File destDir = new File(targetDirectory);if (!destDir.exists()) {destDir.mkdirs();}ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath));ZipEntry zipEntry;byte[] buffer = new byte[1024];while ((zipEntry = zis.getNextEntry()) != null) {File newFile = new File(destDir, zipEntry.getName());if (zipEntry.isDirectory()) {newFile.mkdirs();} else {// 确保父目录存在new File(newFile.getParent()).mkdirs();FileOutputStream fos = new FileOutputStream(newFile);int len;while ((len = zis.read(buffer)) > 0) {fos.write(buffer, 0, len);}fos.close();}zis.closeEntry();}zis.close();callback.onSuccess(targetDirectory);} catch (IOException e) {e.printStackTrace();callback.onFailed(e.getMessage());}}).start();
}

解压回调

为了处理解压过程中的状态,我们也需要一个回调接口:

public interface UnzipCallback {void onSuccess(String targetPath);  // 解压成功void onFailed(String error);        // 解压失败
}

4.断点续传

对于较大的文件下载,可能需要实现断点续传功能。为了实现这一点,我们可以在下载时存储已下载的字节数,并在中断后继续下载。

修改 downloadZipFile 方法,使用 Range 头来支持断点续传:

public void downloadZipFileWithResume(String urlStr, String savePath, DownloadCallback callback) {new Thread(() -> {InputStream input = null;FileOutputStream output = null;HttpURLConnection connection = null;try {File file = new File(savePath);long downloadedLength = file.exists() ? file.length() : 0;URL url = new URL(urlStr);connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(10000);connection.setReadTimeout(10000);connection.setRequestProperty("Range", "bytes=" + downloadedLength + "-");connection.connect();if (connection.getResponseCode() != HttpURLConnection.HTTP_PARTIAL &&connection.getResponseCode() != HttpURLConnection.HTTP_OK) {callback.onFailed("Server returned HTTP " + connection.getResponseCode());return;}int fileLength = connection.getContentLength() + (int) downloadedLength;input = connection.getInputStream();output = new FileOutputStream(file, true);  // 以追加方式写入byte[] buffer = new byte[4096];int bytesRead;long total = downloadedLength;while ((bytesRead = input.read(buffer)) != -1) {total += bytesRead;output.write(buffer, 0, bytesRead);int progress = (int) (total * 100 / fileLength);callback.onProgress(progress);}callback.onSuccess(file.getAbsolutePath());} catch (Exception e) {e.printStackTrace();callback.onFailed(e.getMessage());} finally {try {if (output != null) output.close();if (input != null) input.close();} catch (IOException ignored) {}if (connection != null) connection.disconnect();}}).start();
}

5.调用示例

以下是如何使用我们实现的功能来下载、解压并处理回调:

// 下载地址和存储路径
String zipUrl = "https://example.com/path/to/file.zip";
File downloadDir = context.getExternalFilesDir(null); // 应用私有目录
String zipFilePath = new File(downloadDir, "downloaded_file.zip").getAbsolutePath();
String unzipTargetDir = new File(downloadDir, "unzipped_folder").getAbsolutePath();// 下载 ZIP 文件
downloadZipFile(zipUrl, zipFilePath, new DownloadCallback() {@Overridepublic void onProgress(int progress) {Log.d("Download", "Progress: " + progress + "%");}@Overridepublic void onSuccess(String filePath) {Log.d("Download", "Download completed: " + filePath);// 解压 ZIP 文件unzip(filePath, unzipTargetDir, new UnzipCallback() {@Overridepublic void onSuccess(String targetPath) {Log.d("Unzip", "Unzip completed at: " + targetPath);}@Overridepublic void onFailed(String error) {Log.e("Unzip", "Unzip failed: " + error);}});}@Overridepublic void onFailed(String error) {Log.e("Download", "Download failed: " + error);}
});

6.常见问题与优化建议

在实际开发中,下载和解压 ZIP 文件的过程中会遇到一些常见的问题。以下是一些优化建议和处理方法:

网络连接中断

在进行大文件下载时,网络连接可能会中断,导致下载失败。为了避免重复下载,建议使用断点续传技术。断点续传技术通过记录文件下载的进度,从而在网络中断后可以从中断位置继续下载,而不是重新开始。

优化建议:

  • 使用 Range 请求头来实现文件下载的断点续传(如上文所示)。
  • 在网络中断时,将已经下载的字节数保存在本地文件中,以便恢复下载。

文件解压失败

在解压 ZIP 文件时,如果文件结构复杂或者出现损坏,可能会导致解压失败。确保文件完整性是防止解压失败的关键。

优化建议:

  • 在解压前,可以验证 ZIP 文件的完整性,确保下载完成且未损坏。
  • 使用 ZipFile 类可以简化一些 ZIP 文件的解压操作,并能更好地处理压缩包中的特殊情况(如加密压缩包)。

性能优化

  • 缓冲区大小:在下载和解压文件时,使用适当大小的缓冲区(例如 4096 字节)可以提升性能。
  • UI 线程阻塞:确保所有的网络和解压操作都在后台线程中执行,避免阻塞 UI 线程,导致应用无响应。

文件存储权限问题

在 Android 10 及以上版本,Google 对外部存储的访问权限做出了更严格的限制。你需要使用 getExternalFilesDir() 方法来存储文件,这个目录是私有的,仅限应用本身访问,且不会在卸载应用时删除。

优化建议:

  • 使用 getExternalFilesDir() 或 MediaStore 来确保兼容性。
  • 针对 Android 11 及以上版本,需申请 MANAGE_EXTERNAL_STORAGE 权限以便访问共享存储。

文件大小限制

大文件的下载和解压会占用大量存储空间,尤其是当设备存储较满时,可能会导致下载失败或存储不足的问题。

优化建议:

  • 在下载前,检查设备存储空间是否足够,并提示用户进行清理。
  • 如果需要处理大文件,考虑在下载过程中显示文件大小,并在下载完成前通过 onProgress 更新下载进度。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词