implementation 'com.android.volley:volley:1.1.1'
编写工具VolleyUploadRequest
import com.android.volley.*
import com.android.volley.toolbox.HttpHeaderParser
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileInputStream
import java.lang.Exception
import java.nio.charset.Charset
class VolleyUploadRequest(
url: String, // 地址
val fileName: String, // 文件名
val file: File, // 文件
val fileMime: String, // 文件类型
val listener: Response.Listener,
errorListener: Response.ErrorListener
) : Request(Method.POST, url, errorListener) {
companion object{
private const val boundary = "*****"
}
init {
setShouldCache(false)
retryPolicy = DefaultRetryPolicy(6000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)
}
override fun parseNetworkResponse(response: NetworkResponse?): Response {
return try {
val str = String(response?.data?: byteArrayOf(),
Charset.forName(HttpHeaderParser.parseCharset(response?.headers?: emptyMap())))
Response.success(str, HttpHeaderParser.parseCacheHeaders(response))
} catch (e: Exception) {
Response.error(ParseError(e))
}
}
override fun deliverResponse(response: String) {
listener.onResponse(response)
}
override fun getBodyContentType(): String {
return "multipart/form-data; boundary=$boundary"
}
override fun getBody(): ByteArray {
val bos = ByteArrayOutputStream()
val buffer = StringBuffer()
// --boundary
buffer.append("--$boundary\r\n")
// Content-Disposition: form-data; name="fileName"; filename="xxx.png";
buffer.append("Content-Disposition: form-data; ")
buffer.append("name=\"$fileName\"; ")
buffer.append("filename=\"${file.name}\";\r\n")
// Content-Type: image/png
buffer.append("Content-Type: $fileMime;\r\n")
// \r\n
buffer.append("\r\n")
// 写入
bos.write(buffer.toString().toByteArray(Charset.forName("utf-8")))
// 文件二进制数据
val fis = FileInputStream(file)
val bytes = ByteArray(1024)
var length = fis.read(bytes)
while (length >= 0) {
bos.write(bytes, 0, length)
length = fis.read(bytes)
}
bos.write("\r\n".toByteArray(Charset.forName("utf-8")))
fis.close()
// 结尾
bos.write("--$boundary--\r\n".toByteArray(Charset.forName("utf-8")))
return bos.toByteArray()
}
}
使用
val uploadReq = VolleyUploadRequest(
"https://xxx.com/RDphotoUp",
"image", file, "image/jpeg",
object : Response.Listener{
override fun onResponse(response: String?) {
if (response == null || response.isEmpty()) {
// 上传失败
return
}
LogUtils.e("RDphotoUp", response)
// 上传成功
}
},
Response.ErrorListener { error ->
// 上传出错
}
)
// 加入网络请求排列
HttpWorker.getInstance(this).addToRequestQueue(uploadReq)
HttpWorker
import android.content.Context
import android.graphics.Bitmap
import android.util.LruCache
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.toolbox.ImageLoader
import com.android.volley.toolbox.Volley
class HttpWorker constructor(context: Context) {
companion object {
@Volatile
private var INSTANCE: HttpWorker? = null
fun getInstance(context: Context) =
INSTANCE ?: synchronized(this) {
INSTANCE ?: HttpWorker(context).also {
INSTANCE = it
}
}
}
val imageLoader: ImageLoader by lazy {
ImageLoader(requestQueue,
object : ImageLoader.ImageCache {
private val cache = LruCache(20)
override fun getBitmap(url: String): Bitmap {
return cache.get(url)
}
override fun putBitmap(url: String, bitmap: Bitmap) {
cache.put(url, bitmap)
}
})
}
val requestQueue: RequestQueue by lazy {
// applicationContext is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
Volley.newRequestQueue(context.applicationContext)
}
fun addToRequestQueue(req: Request) {
requestQueue.add(req)
}
}
完事
作者:YD-10-NG