文件被分为2 MB的块。
val channel = AndroidChannelBuilder
.forAddress("server address", 443)
.context(this)
.intercept(GrpcAuthorizationInterceptor())
.build()
val source = FileInputStream(File("/sdcard/Movies/Movie.mp4"))
FileServiceGrpc.newStub(channel)
.uploadFile(object : ClientResponseObserver<UploadFileRequest, UploadFileResponse> {
override fun beforeStart(requestStream: ClientCallStreamObserver<UploadFileRequest>) {
var counter = 0
requestStream.setOnReadyHandler {
while (requestStream.isReady) {
Log.d("MainActivity", "sending ${counter++} chunk")
val bytes = ByteArray(2 * 1024 * 1024)
source.read(bytes)
val byteString = ByteString.copyFrom(bytes)
val request = UploadFileRequest.newBuilder()
.setData(byteString)
.setExtension(UploadFileRequest.Extension.MP4)
.build()
requestStream.onNext(request)
}
}
}
override fun onNext(value: UploadFileResponse) {
}
override fun onError(t: Throwable) = throw t
override fun onCompleted() {
}
})
每次运行此代码时,应用程序都会崩溃:
java.lang.OutOfMemoryError: Failed to allocate a 24 byte allocation with 125656 free bytes and 122KB until OOM, target footprint 201326592, growth limit 201326592; failed due to fragmentation (largest possible contiguous allocation 0 bytes)
sending 0 chunk
...
sending 61 chunk
重要的是,两者之间没有延迟
sending x chunk
日志条目,这意味着
setOnReadyHandler
requestStream.isReady
旗杆
true
.
问题似乎就在这里:尽管之前的数据还没有被发送,并且被gRPC缓冲,
isReady
退货
. 的JavaDoc
我准备好了
方法如下:
* If {@code true}, indicates that the observer is capable of sending additional messages
* without requiring excessive buffering internally. This value is just a suggestion and the
* application is free to ignore it, however doing so may result in excessive buffering within the
* observer.
设置
android:largeHeap="true"
AndroidManifests.xml
解决了这个问题,但对我来说,这似乎只是一个解决办法。
OutOfMemoryError
?