Android 2022-05-14 14:59:56 阅读数:86
For some unknown reason , In the near future, I will publish a large number of articles on theory or source code . Most of these articles are my notes from previous years , Or you didn't have time to take notes before . It is more suitable for developers who have a certain understanding of the relevant framework source code . Otherwise, it may cause discomfort ,
call RealCall.newRealCall establish Call
Next, let's look at dispatcher().executed And then look at it getResponseWithInterceptorChain Method
In this method, a connector is built first , Then execute the interceptor
This method is finally adjusted to Dispatcher.enqueue
Dispatcher The role of is to distribute requests , That is, he is used to manage Call And distribution Call Of . He also maintains a thread pool
Dispatcher Three queues are maintained internally ：
Dispatcher There is not much complex logic in the , It mainly explains several important methods
It should be noted that client.interceptors() The interceptor obtained will be called anyway and client.networkInterceptors() The interceptor obtained will only call... Before the request goes to the real network request （ If the request uses a cache , Or if the real request ends before it starts, it will not call ）
The redirection interceptor actually maintains a loop internally . If the current request supports redirection , Then the responsibility chain will be re executed at the current position of the responsibility chain （ Will retry multiple times ）. And that is , It attempts to reuse the previous connection
ConnectInterceptor To get or create a connection in the cache , It's actually three handshakes . However, if there are available connections in the cache pool, you don't need to shake hands three times , This is the main function of the connector --- Save us three handshakes
Briefly describe the process of obtaining a connection （ Follow this idea when reading code ）：
First check StreamAllocation Current in class connection Is it available , If not available, turn off its socket
Try to get the connection assignment from the connection pool to StreamAllocation.connection, If the acquisition is successful, reuse it directly
If the first 2 Step did not succeed , And the request is http2, Then try to use again route Get multiplexed connections
If the third part still doesn't get the connection , Then create a connection and add it to the cache pool
If the connection is number 4 Created in step , You need three handshake connections before you can use
If we were first 5 In step, after the connection is created , It is found that other requests have created a connection , Then we kill the connection we created ourselves , Then use the connection created by other requests to return .
findConnection There will be two attempts to get a connection from the connection pool , The first time is not to pass route To get . And the second time is through route To get .
The reason why there will be a second acquisition is http2 With multiplexing The concept of , Each connection can have multiple stream Of
http2 Multiplexing is the same tcp Links can execute multiple functions concurrently http request . I haven't seen it in the development process http2 Well , So there's no need to go too deep here
Okhttp You can use synchronous and asynchronous requests to request the network to obtain data , The request process is to build the request parameters , structure Call object , Then get the return data synchronously or asynchronously .
Both synchronous and asynchronous requests will eventually Call Dispatch to Dispatcher Class ,
The difference between them is ：
Synchronous request mode will Call Join the synchronization request queue and execute the request .
The asynchronous request may put the request in the executing asynchronous request queue , It may also be added to the asynchronous request preparation queue . If the number of asynchronous requests we are currently executing is greater than the maximum number of concurrent requests , Then the request will be added to the preparation queue . After each asynchronous request is completed, it will try to add the request in the preparation queue to the executing queue .
It should be noted that asynchronous requests are executed using thread pool
Both methods will eventually call getResponseWithInterceptorChain Get the final data .
getResponseWithInterceptorChain It maintains a chain of responsibility . There are multiple connectors in this responsibility chain , Include 1 Retry the interceptor 、2 Bridge interceptors 、3 Cache interceptor 、4 Connection interceptor 、5 Network request interceptor . Our request parameters will be processed by these interceptors , The process is from 1->5, return Response The result will be from 5->1.
It actually includes custom interceptors
The subsequent process is to return the data to the calling place , The synchronization request directly returns the result , The asynchronous request uses the callback method to callback the result .
For example, when you use traversal to implement the chain of responsibility , When you want to try again, when the request gets CacheInterceptor, Find out CacheInterceptor It contains the logic we executed last time , He needs to deal with this residual logic more , It increases the workload .