Android中用Volley将API返回字节流保存为PDF的实现问询
用Volley扩展Request实现Android的PDF文件下载与保存
刚好我之前开发Android应用时,也碰到过要从API下载并保存PDF的需求——Volley默认的Request类型都是处理字符串或者JSON的,没法直接拿二进制文件的字节流,所以我专门扩展了Request类做了个ByteArrayRequest,直接获取原始字节数据来处理。下面是完整的实现代码:
package br.com.tarcisojunior.myapp; import android.support.annotation.NonNull; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.toolbox.HttpHeaderParser; /** * Created by tarcisojunior on 18/04/18. */ public class ByteArrayRequest extends Request<byte[]> { private final Response.Listener<byte[]> mListener; public ByteArrayRequest(int method, String url, Response.Listener<byte[]> listener, Response.ErrorListener errorListener) { super(method, url, errorListener); mListener = listener; } @Override protected Response<byte[]> parseNetworkResponse(NetworkResponse response) { // 直接返回API响应的原始字节数组,跳过字符串解析步骤 return Response.success(response.data, HttpHeaderParser.parseCacheHeaders(response)); } @Override protected void deliverResponse(byte[] response) { // 将字节数据传递给回调 mListener.onResponse(response); } }
怎么用这个类下载并保存PDF?
写完这个自定义Request后,就可以像用普通Volley请求一样发起下载,拿到字节数组后再保存成PDF文件:
// 替换成你的PDF文件API地址 String pdfApiUrl = "https://your-api-url.com/file.pdf"; // 实例化ByteArrayRequest ByteArrayRequest pdfRequest = new ByteArrayRequest( Request.Method.GET, pdfApiUrl, // 请求成功的回调:拿到字节数组后保存为PDF pdfBytes -> { // 这里可以指定文件保存路径,比如应用内部存储 String savePath = getFilesDir() + "/downloaded_file.pdf"; savePdfFromBytes(pdfBytes, savePath); }, // 请求失败的回调 error -> { // 处理下载失败的情况,比如弹提示 Toast.makeText(getApplicationContext(), "PDF下载失败", Toast.LENGTH_SHORT).show(); } ); // 将请求加入Volley队列 Volley.newRequestQueue(getApplicationContext()).add(pdfRequest);
补充:字节数组转PDF文件的辅助方法
上面用到的savePdfFromBytes方法可以这么实现:
private void savePdfFromBytes(byte[] pdfBytes, String savePath) { FileOutputStream outputStream = null; try { File pdfFile = new File(savePath); // 创建文件(如果不存在) if (!pdfFile.exists()) { pdfFile.createNewFile(); } outputStream = new FileOutputStream(pdfFile); outputStream.write(pdfBytes); Toast.makeText(getApplicationContext(), "PDF保存成功,路径:" + savePath, Toast.LENGTH_LONG).show(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "保存PDF出错", Toast.LENGTH_SHORT).show(); } finally { // 记得关闭流 if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
为什么要这么做?
因为PDF是二进制格式的文件,如果用Volley默认的StringRequest,会把字节数据当成字符串解析,很容易出现乱码或者文件损坏的情况。而这个ByteArrayRequest直接获取API返回的原始字节数组,完美保留了文件的完整性,这样保存后的PDF就能正常打开啦。
内容的提问来源于stack exchange,提问作者Tarciso Junior
相关产品推荐
相关产品推荐

