Android使用OkHttp实现文件上传到服务器并显示进度

15 下载量 24 浏览量 更新于2024-09-01 1 收藏 101KB PDF 举报
"Android使用OkHttp进行文件上传到服务器,并且显示上传进度" 在Android开发中,有时我们需要将用户选择的文件上传到服务器。OkHttp是一个高效、易用的网络库,支持HTTP/2和SPDY协议,可以方便地处理文件上传任务。本教程将介绍如何使用OkHttp在Android中实现文件上传到服务器,并展示上传进度。 首先,我们需要在服务器端设置一个接收文件的Servlet。在上一讲中提到,我们创建了一个名为`UploadFileServlet`的Servlet,它使用`@.WebServlet("/UploadFileServlet")`注解来指定URL映射,以及`@MultipartConfig`注解来支持多部分表单数据,这通常用于文件上传。以下是一个简单的`UploadFileServlet`的实现: ```java @WebServlet("/UploadFileServlet") @MultipartConfig public class UploadFileServlet extends HttpServlet { private static final long serialVersionUID = 1L; public UploadFileServlet() { super(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doPost=="); request.setCharacterEncoding("utf-8"); Part part = request.getPart("file"); String header = part.getHeader("content-disposition"); // 在这里处理文件,例如保存到服务器的某个路径 // ... } } ``` 在Android客户端,我们将使用OkHttp来实现文件上传。首先,确保在项目中添加了OkHttp和Okio的依赖。接着,我们可以创建一个方法来执行文件上传操作: ```kotlin fun uploadFile(file: File, progressListener: (Int) -> Unit) { val requestBody = createRequestBody(file) val request = Request.Builder() .url("http://yourserver.com/UploadFileServlet") // 替换为你的服务器地址 .post(requestBody) .build() val client = OkHttpClient() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { // 处理失败情况,如显示错误信息 } override fun onResponse(call: Call, response: Response) { if (response.isSuccessful) { // 上传成功,处理响应 } else { // 上传失败,处理错误 } } }) val uploadListener = object : ProgressRequestBody.ProgressListener { override fun update(current: Long, total: Long, done: Boolean) { val progress = (current.toDouble() / total.toDouble()) * 100 progressListener.invoke((progress * 100).toInt()) } } requestBody.listener = uploadListener } ``` 在上述代码中,`createRequestBody`方法用于将文件转换为`RequestBody`,以便于OkHttp发送: ```kotlin private fun createRequestBody(file: File): RequestBody { val fileReader = FileInputStream(file) val fileLength = file.length() val requestBody = ProgressRequestBody(fileReader, fileLength) return requestBody } class ProgressRequestBody constructor( private val fileInputStream: FileInputStream, private val contentLength: Long ) : RequestBody() { private var listener: ProgressListener? = null override fun contentType(): MediaType? { return MediaType.parse("application/octet-stream") } override fun writeTo(sink: BufferedSink) { val buffer = Buffer() val byteCount = 1024 var read: Int while (fileInputStream.read().also { read = it } != -1) { buffer.writeByte(read) sink.write(buffer, byteCount) buffer.clear() } sink.flush() } fun setListener(listener: ProgressListener?) { this.listener = listener } interface ProgressListener { fun update(current: Long, total: Long, done: Boolean) } } ``` 在`ProgressRequestBody`类中,我们实现了`writeTo`方法来读取文件并写入到网络流中。同时,我们定义了一个`ProgressListener`接口来监听上传进度,并在`uploadFile`方法中设置了监听器。 通过上述步骤,你可以在Android应用中使用OkHttp实现文件上传到服务器,并在上传过程中显示进度。请注意,实际应用中需要对网络请求进行异常处理,并根据服务器返回的状态码判断上传是否成功。同时,根据实际情况,你可能还需要处理文件名、文件类型等额外信息。