3

有没有人能够使用 CRONET 在 Android 中完成发送 multipart/form-data POST?我尝试使用 POST 请求将图像/png 上传到我们的服务器没有成功,我很好奇是否有人有。

注意:我只需要基于 CRONET 的解决方案

发布方法示例:

val myBuilder = CronetEngine.Builder(context)
// Enable caching of HTTP data and
// other information like QUIC server information, HTTP/2 protocol and QUIC protocol.
val cronetEngine: CronetEngine = myBuilder
    .enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024.toLong())
    .enableHttp2(true)
    .enableQuic(true)
    .build()
val executor: Executor = Executors.newSingleThreadExecutor()
val requestBuilder = cronetEngine.newUrlRequestBuilder(
    "FULL-URL",
    MyUrlRequestCallback(),
    executor
)
// Content-Type is required, removing it will cause Exception
requestBuilder.addHeader("Content-Type","application/json; charset=UTF-8")
requestBuilder.setHttpMethod("POST")
val myUploadDataProvider = MyUploadDataProvider()
requestBuilder.setUploadDataProvider(myUploadDataProvider,executor)
val request: UrlRequest = requestBuilder.build()
request.start()

MyUploadDataProvider 类:

import android.util.Log
import org.chromium.net.UploadDataProvider
import org.chromium.net.UploadDataSink
import java.lang.Exception
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets

private const val TAG = "MyUploadDataProvider"
//TODO replace username and passowrd "_user & _pass"
var string: String ="{\"username\":\"_user\",\"password\":\"_pass\"}"
val charset = StandardCharsets.UTF_8

class MyUploadDataProvider() : UploadDataProvider() {

    override fun getLength(): Long {
    val size:Long = string.length.toLong()
    Log.e(TAG,"Length = "+size)
    return size
    }

    override fun rewind(uploadDataSink: UploadDataSink?) {
    Log.e(TAG,"REWIND IS CALLED")
    uploadDataSink!!.onRewindSucceeded()
    }

    override fun read(uploadDataSink: UploadDataSink?, byteBuffer: ByteBuffer?) {
    Log.e(TAG,"READ IS CALLED")
    byteBuffer!!.put(string.toByteArray(charset))
    //byteBuffer.rewind()
    //For chunked uploads, true if this is the final read. It must be false for non-chunked uploads.
    uploadDataSink!!.onReadSucceeded(false)
    }

}
4

2 回答 2

0

要上传文件,我宁愿create()使用UploadDataProviders. 借助这些方法,您可以创建一个UploadDataProvider用于上传 的FileFileDescriptor甚至是一个byte数组。例如,要上传一个空的字节数组,我可以这样做:

...
val myUploadDataProvider = UploadDataProviders.create(byteArrayOf())
...

或者,如果我有一个File对象,我也可以将它直接传递给 create 方法:

...
val myUploadDataProvider = UploadDataProviders.create(someFile)
...

因此,整个代码如下所示:

...
    val myBuilder = CronetEngine.Builder(this)
    val cronetEngine: CronetEngine = myBuilder
            .enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024.toLong())
            .enableHttp2(true)
            .enableQuic(true)
            .build()
    val executor: Executor = Executors.newSingleThreadExecutor()
    val requestBuilder = cronetEngine.newUrlRequestBuilder(
            "http://ptsv2.com/",
            object : UrlRequest.Callback() {
                override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
                }

                override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {

                }

                override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
                }

                override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
                }

                override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {

                }

            },
            executor
    )
    requestBuilder.addHeader("Content-Type","application/json; charset=UTF-8")
    requestBuilder.setHttpMethod("POST")
    val myUploadDataProvider = UploadDataProviders.create(byteArrayOf())
    requestBuilder.setUploadDataProvider(myUploadDataProvider,executor)
    val request: UrlRequest = requestBuilder.build()
    request.start()
...
于 2021-03-30T23:20:33.463 回答
0

是的,cronet 和 volley 是谷歌官方支持的库,但也请考虑谷歌的另一面......谷歌也官方支持改造......因为它的快速和更少的样板代码......请阅读一些博客,也可以访问 udacity纳米学位课程,说它改造最适合网络......

于 2021-04-01T06:03:43.070 回答