Why I will get this exception in writeTo
function?
2019-07-02 12:17:03.525 13663-14248/com.zoinla.pegasus_work E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher Process: com.xxx, PID: 13663 java.lang.ArrayIndexOutOfBoundsException: size=2048 offset=0 byteCount=-1 at okio.Util.checkOffsetAndCount(Util.java:30) at okio.Buffer.write(Buffer.java:1096) at okio.Buffer.write(Buffer.java:54) at com.xxx.ProgressRequestBody.writeTo(ProgressRequestBody.kt:33) at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:173) at okhttp3.MultipartBody.writeTo(MultipartBody.java:114) at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:202)
ProgressRequestBody
open class ProgressRequestBody(val file: File, val listener: UploadCallbacks) : RequestBody() {
override fun contentType(): MediaType? {
return MediaType.parse("$content_type/")
}
override fun writeTo(sink: BufferedSink) {
val fileLength = file?.length()
val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
val `in` = FileInputStream(file)
var uploaded: Long = 0
try {
var read: Int
val handler = Handler(Looper.getMainLooper())
do {
read = `in`.read(buffer)
handler.post(ProgressUpdater(uploaded, fileLength!!))
uploaded += read.toLong()
sink.write(buffer, 0, read)
if (read == -1) {
break
}
} while (true)
} finally {
`in`.close()
}
}
override fun contentLength(): Long {
return file.length()
}
val content_type = ""
companion object {
val DEFAULT_BUFFER_SIZE = 2048
}
private inner class ProgressUpdater(private val mUploaded: Long, private val mTotal: Long) : Runnable {
override fun run() {
listener?.onProgressUpdate((100 * mUploaded / mTotal).toInt())
}
}
interface UploadCallbacks {
fun onProgressUpdate(percentage: Int)
fun onError()
fun onFinish()
}
}
It pointed to this line
sink.write(buffer, 0, read)
Yes, this will happen when read == -1
. You should test it before you use it:
do {
read = `in`.read(buffer)
handler.post(ProgressUpdater(uploaded, fileLength!!))
if (read == -1) {
break
}
uploaded += read.toLong()
sink.write(buffer, 0, read)
} while (true)
Or perhaps:
do {
read = `in`.read(buffer)
if (read == -1) {
break
}
uploaded += read.toLong()
sink.write(buffer, 0, read)
handler.post(ProgressUpdater(uploaded, fileLength!!))
} while (true)