Red de conocimiento informático - Aprendizaje de programación - Análisis OKHttp

Análisis OKHttp

Analice los tres pasos y las tres líneas principales del marco de acceso a la red:

1. ¿Dónde se envía la solicitud?

call.enqueue()------equeue()

Acceda al valor de solicitud unificado de la máquina de destino, el valor predeterminado es 5

Se agrega cuando < ?5 Ejecute la cola de estado; de lo contrario, únase a la cola de estado de espera

2. ¿Quién maneja la solicitud?

En el grupo de subprocesos de executorService, el subproceso principal es 0 y el número máximo es maxValue. El grupo de subprocesos mantiene una cola de espera internamente. OKHTTP es una cola sin capacidad, lo que significa que las solicitudes entrantes deben ser. procesado y no se crearán subprocesos, por lo que será maxValue.

Luego vaya a la clase AsyncCall y llame al método ejecutar () aquí es donde realmente se procesa la solicitud, y luego vaya al método getResponsewithInterceptorChain (), que es un modelo de cadena de responsabilidad. /p>

Modelo de cadena de responsabilidad: hay una cadena con múltiples nodos, y cada nodo tiene éxito o falla. La ventaja de esto es que cuando accedemos al servidor, podemos filtrarlo e interceptar solicitudes no válidas.

Interceptor de reintentos, interceptor de puente, interceptor de caché, interceptor de conexión, interceptor de red.

Solo se enviarán al servidor las solicitudes que hayan sido interceptadas y filtradas.

3. ¿Cómo mantener las solicitudes?

client.dispatch

Inicio de solicitud HTTP:

client=new OkHttpClient();

Solicitud de solicitud=new Request.Builder( ).url("tu url").build();

// Solicitud de inicio sincrónico

Respuesta syncResponse=client.newCall(request).execute();

// Solicitud de inicio asíncrona

client.dispatch

// Solicitud de inicio síncrona:

client.dispatch

// Solicitud de inicio sincrónico.

.enqueue(newCallback(){

@Override

public void onFailure(@NotNullCallcall, @NotNullIOExceptione){

}

@ Anular<

public void onResponse(@NotNullCallcall,@NotNullResponseresponse) throwsIOException{

}

Programa de llamada:

p> p>

new OKHTTPClient() -----" client.newCall(solicitud)----->execute() Solicitud sincrónica------->RealCall#getResponseWithInterceptorChain( )--- -- --- ->RealInterceptorChain#proceed(solicitud)

new OKHTTPClient() -----" client.newCall(solicitud)----->enqueue() Solicitud asincrónica--- -- Dispatcher.equeue( )----

---->Dispatcher#promoteAndExecute( )------>executeOn( )----->ejecutar( )--- ------------------------ ------------------------- --- ---------->RealCall#getResponseWithInterceptorChain( )--------->RealInterceptorChain#proceed( request)

Hay cinco interceptores en OKHTTP: caché interceptor, Interceptor de conexión de red,

Tres pasos para personalizar el interceptor:

chain.request()

chain.proceed()

devolver respuesta;

OKHTTP puede configurar x509trustManager para establecer el certificado de confianza TLS:

Hay un peligro oculto en esto, es decir, primero debe aceptar el certificado del sistema y luego aceptar el certificado local. De lo contrario, el acceso a algunos enlaces será anormal.

La cola de solicitudes de OKHTTP utiliza SynchronousQueue. Esta cola se caracteriza por una capacidad de 0 y las solicitudes se procesan inmediatamente cuando llegan.

Pregunta de la entrevista 1: ¿Cómo es la cadena de responsabilidad? en OKHTTP unidos? ¿Cómo realizar el cambio de hilo para los datos devueltos por la solicitud?

Respuesta: En serie, al agregar varios interceptores a un conjunto, cree un objeto RealInterceptorChain, pase el conjunto de interceptores y pase un índice con un índice de 0, que es esencialmente una subclase de cadena, la devolución de llamada interna es para el método de devolución de llamada proceder (). En el método proceder (), el objeto RealInterceptorChain se crea en un bucle y el índice se incrementa en 1 cada vez que se elimina un interceptor, el interceptor llama al método de devolución de llamada. (), y se ejecuta internamente. Intercepta, completa lo que puedes hacer y luego devuelve la respuesta, y luego concatena la ejecución de cada interceptor de esta manera.

El método asincrónico llamará al método enqueue(), dentro de client.dispatcher ().enqueue (new AsyncCall (responseCallback)); este AsyncCall es esencialmente un Runable y el método se ejecuta en Runable. Llame a ejecutar (), que es un método a implementar. En el método de implementación ejecutar (), llame a getResponseWithInterceptorChain (), que intercepta la solicitud. El resultado se devolverá a la función de devolución de llamada onResponse (). OKHTTP no nos devolverá al hilo principal. El siguiente paso lo realizamos nosotros mismos. Podemos usar un controlador para completar el siguiente paso o usar runOnUIThread () para volver al hilo principal.

Después de obtener el resultado del hilo secundario, si desea actualizar la interfaz de usuario en el hilo principal, puede usar tres métodos:

(1) runOnUiThread(): en realidad, se realiza internamente el juicio del subproceso. Si es el subproceso principal, se ejecutará directamente; de ​​lo contrario, se ejecutará utilizando el controlador predeterminado creado en la Actividad, que llamará a handler.post (), y este método de publicación también llame a sendMessage()

(2) handler.post (new Runnable{}), cuando utilice el método del controlador para volver al hilo principal, tenga en cuenta que la creación de instancias del controlador debe colocarse en el hilo principal, no en el hilo secundario recién abierto. Esto se debe a que los controladores se crean en el hilo principal, y los controladores creados en el hilo principal utilizarán el Looper del hilo principal de forma predeterminada, lo que significa que si la interfaz de usuario se puede actualizar depende principalmente de si el Looper está en el hilo principal. Porque Looper se ejecuta en el hilo que lo creó.

handler.post()----->sendMessageDelayed(getPostMessage(r), 0); esencialmente envía un mensaje como sendMessage().

(3) view.post(new Runnable{}), regrese y determine si el campo adjuntoInfo de la vista está vacío. Si no está vacío, obtenga el objeto controlador en adjuntarInfo y luego llame. el controlador El método de publicación realiza el cambio de hilo.

Pregunta de la entrevista 2: ¿Manejador sendMessageDelay()? ¿Cómo ejecutar?

El método sendMessageDelay() agregará el tiempo de retraso a la hora actual y luego asignará este tiempo a msg.when en el método enqueueMessage() de la clase MessageQueue, que representa el tiempo de ejecución del mensaje. , y luego el poller Looper llamará al bucle cuando el bucle reciba un mensaje de la cola de mensajes, y luego llamará al método next() de messageQueue para obtener el siguiente mensaje. Este método comparará internamente la hora actual con msg.when. Si es menor que msg.when, significa que no se ha alcanzado el tiempo de ejecución y luego obtendrá la diferencia entre los dos la próxima vez con el método NativePollOnce (). Cuando se llama en el bucle, Linux reordenará internamente los mensajes individuales. Cuando finalice el tiempo de ejecución, el mensaje se devolverá al Looper.

Pregunta de la entrevista 3: Glide cache, ¿cómo almacenarlo?

Pregunta de la entrevista 4: ¿Mecanismo de implementación de actualización, cambio de hilo después de la devolución de datos?

Retrofit utiliza internamente servidores proxy dinámicos, anotaciones y reflexión para implementar la encapsulación de la interfaz, y utiliza la implementación okhttp para implementar operaciones de solicitud. De hecho, durante el proceso de creación de Retrofit, en el método de construcción.

if (callbackExecutor = == null) {

callbackExecutor = platform.defaultCallbackExecutor();

}

Y esta llamada platform.defaultCallbackExecutor(); ,

clase final estática Androidextends Platform {

Android() {

super(Build.VERSION.SDK_INT >=24);

}

@Override

? public ExecutordefaultCallbackExecutor() {

devolver nuevo MainThreadExecutor();

Es decir, se crea el objeto MainThreadExecutor().

la clase final estática MainThreadExecutor implementa el Ejecutor {

handerhandler final privado =new Handler(Looper.getMainLooper());

?@Override

? public void ejecutar(Runnable r) {

handler.post(r

?}

}

MainThreadExecutor; es una clase final interna estática, que en realidad crea un controlador y lo pasa al Looper del hilo principal, y el callbackExecutor creado antes es una clase de interfaz que implementa la devolución de datos de la solicitud, de modo que los datos de la solicitud se puedan pasar a través del El controlador se devuelve al hilo principal.

Pregunta de la entrevista 5: ¿A qué capa del protocolo HTTPS pertenece TLS?

Respuesta: Es un protocolo entre la capa de aplicación y la capa de transporte.

La capa inferior de Okhttp solicita y recibe respuestas a través de sockets Java (porque HTTP se basa en TCP). pero okhttp implementa el concepto de agrupación de conexiones, es decir, para múltiples solicitudes al mismo host, en realidad puede usar una conexión de socket en lugar de enviar una solicitud HTTP cada vez. En lugar de cerrar el socket subyacente cada vez que se envía una solicitud HTTP, implementando así el concepto de grupo de conexiones, okhttp utiliza una capa de encapsulación de la biblioteca OKIO para operaciones de lectura y escritura de socket.