0

我正在开发 android 应用程序,在其中我使用 cronet 将数据发送到服务器现在我想将数据发送到 json 对象中的服务器但不知道如何发送对象?

以下是我的 GET 方法(工作)代码段。

谁能分享如何在 android cronet 中使用 POST 方法?

依赖项

 implementation 'org.chromium.net:cronet-embedded:71.3578.98'

主要活动

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.chromium.net.CronetEngine
import java.util.concurrent.Executors

class MainActivity : AppCompatActivity() {

    companion object {
        // Web page url
        private const val JSON_PLACEHOLDER_API_URL = "https://jsonplaceholder.typicode.com/todos/1"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Build a Cronet engine
        val cronetEngine =
            CronetEngine.Builder(this)
                .enableBrotli(true)
                .build()

        // Build the request
        val request =
            cronetEngine.newUrlRequestBuilder(
                JSON_PLACEHOLDER_API_URL,
                RequestCallback(),
                Executors.newSingleThreadExecutor()
            ).build()

        // Start the request
        request.start()
    }
}

请求回调

import android.util.Log
import org.chromium.net.CronetException
import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo
import java.nio.ByteBuffer
import java.nio.charset.Charset


/**
 * Different methods are invoked for different response status
 */

class RequestCallback : UrlRequest.Callback() {

    companion object {
        // Log cat tag
        private val TAG = RequestCallback::class.java.simpleName
    }

    override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
        Log.i(TAG, "Response Started")
        val statusCode = info?.httpStatusCode
        Log.i(TAG, "Status Code $statusCode")
        if (statusCode == 200) {
            // Read the buffer
            request?.read(ByteBuffer.allocateDirect(32 * 1024))
        }
    }

    override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
        Log.i(TAG, "Response Completed")

        // Flip the buffer
        byteBuffer?.flip()

        // Convert the byte buffer to a string
        byteBuffer?.let {
            val byteArray = ByteArray(it.remaining())
            it.get(byteArray)
            String(byteArray, Charset.forName("UTF-8"))
        }.apply {
            Log.d(TAG, "Response: $this")
        }

        // Clear the buffer
        byteBuffer?.clear()

        // Read the buffer
        request?.read(byteBuffer)
    }

    override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
        Log.e(TAG, "Response Failed: ${error?.message}")
    }

    override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
        Log.i(TAG, "Response Succeeded")
    }

    override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
        Log.i(TAG, "Response Redirect to $newLocationUrl")
        request?.followRedirect()
    }

    override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
        super.onCanceled(request, info)
        Log.i(TAG, "Response cancelled")
    }
}

输出

Response: {
      "userId": 1,
      "id": 1,
      "title": "delectus aut autem",
      "completed": false
    }
4

1 回答 1

2

例子:

    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)
    }

}
于 2020-04-11T11:50:08.017 回答