我的活动中有以下代码
onCreate()
fun onCreate() {
val channel = AndroidChannelBuilder.forAddress(someEndPoint, port)
.context(applicationContext)
.build()
val stub: ClientLoggerGrpc.ClientLoggerBlockingStub =
ClientLoggerGrpc.newBlockingStub(channel)
val request = Service.ClientLogRequest.newBuilder()
.setMsg("Hello world!")
.setLogLevel(Service.LogLevel.Info)
.build()
val response = stub.log(request)
Log.d(TAG, "onCreate: $response")
}
正如我们在这里看到的,我没有切换到后台线程,而是使用
BlockingStub
,但它仍然不会使应用程序崩溃 NetworkOnMainThreadException
。
即使使用阻塞存根,GRPC 是否会自动切换到 BG 线程,或者 GRPC 是否会以不同的方式执行某些操作,从而使 GRPC 能够绕过引发
NetworkOnMainThreadException
的检查?
gRPC Java 本质上是异步的。
io.grpc.ClientCall
,如制作拦截器时所见,是 gRPC 核心执行 RPC 的 API,并且是带有回调的异步 API。存根层位于 ClientCall 之上,并将其转换为阻塞 API。 I/O 在两个独立的线程上完成:一个用于读取,一个用于写入。
大多数 HTTP/2 客户端的行为类似于单独处理 I/O,因为 HTTP/2 将多个交换复用到单个连接上,并且需要同时读取和写入。