OkHttp + Retrofit example. From introducing dependencies, to writing interfaces, to making network requests.
Introduction of depend on
Introduce dependencies, using Retrofit2.
Implementation 'com. Squareup. Retrofit2: retrofit: 2.1.0' implementation 'com. Squareup. Retrofit2: converter - gson: 2.1.0' Implementation 'com. Squareup. Retrofit2: adapter - rxjava: 2.1.0'Copy the code
The query@Query
For example, the URL https://base_url/backend-service/config? Env =dev, the query content follows the question mark. For both GET and POST, use the @query annotation. Otherwise, an exception will be reported.
URL padding and concatenation
Pure URL padding can be annotated with @path. For example, the following POST request.
@POST("user-service/user/{uid}/token/refresh")
Call<RefreshTokenResp> refreshToken(@Path("uid") String uid, @Query("token") String token);
Copy the code
GET takes the parameters of the query
public interface CfgService { @GET("backend-service/config") Call<ServerCfgResp> getServerCfg(@Query("env") String env); }Copy the code
POST, with parameters for the query and body
public interface UserService {
@POST("user-service/login")
Call<LoginResp> login(@Query("lenovoST") String token, @Query("realm") String realm,
@Body RequestBody body);
@POST("user-service/logout")
Call<CommonEntity> logout(@Query("token") String token, @Body RequestBody body);
}
Copy the code
RequestBody is created when called; Start by investigating the type of body the backend accepts.
Map<String, String> map = new HashMap<>();
map.put("system", "Android");
map.put("phoneBrand", Build.BRAND);
map.put("modelNum", Build.MODEL);
Gson gson = new Gson();
String bodyJson = gson.toJson(map);
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), bodyJson);
Copy the code
Initialize OkHttpClient; All SSL certificates are trusted here (this is not recommended in formal environments).
private CfgService cfgService; public void initService() { SSLSocketFactory sslSocketFactory = null; try { sslSocketFactory = SSLUtils.getSSLSocketFactory(); } catch (Exception e) { e.printStackTrace(); } OkHttpClient.Builder builder = new OkHttpClient.Builder(); if (sslSocketFactory ! = null) { Log.d(TAG, "sslSocketFactory ! = null"); builder.sslSocketFactory(sslSocketFactory); } else { Log.w(TAG, "sslSocketFactory == null"); } builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; // force return true}}); OkHttpClient lenClient = builder.build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(ServerCfg.HOST_URL) .client(lenClient) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); cfgService = retrofit.create(CfgService.class); }Copy the code
Call network request
mNetworkManager.getUserApi().login(mLenovoToken, ServerCfg.RID, requestBody).enqueue(new Callback<LoginResp>() { @Override public void onResponse(Call<LoginResp> call, final Response<LoginResp> response) { //... } @Override public void onFailure(Call<LoginResp> call, final Throwable t) { //... }});Copy the code
Trust SSL on all servers
This is not recommended
Public class SSLUtils {/** * @return trust all servers */ public static SSLSocketFactory getSSLSocketFactory() throws Exception { SSLSocketFactory sslSocketFactory = null; SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{createTrustAllManager()}, new SecureRandom()); sslSocketFactory = sslContext.getSocketFactory(); return sslSocketFactory; } public static X509TrustManager createTrustAllManager() { X509TrustManager tm = null; try { tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {//do nothing, } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {//do nothing, } public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0]; }}; } catch (Exception e) { } return tm; }}Copy the code
Service use IO. Reactivex. Observables
import io.reactivex.Observable; // @post ("feedbackAction") Observable<UserFeedback> userFeedback(@Query("appVersion") String appVersion, @Query("phoneModel") String phoneModel, @Query("phoneOsVersion") String osVersion, @Query("submitContent") String content);Copy the code
Examples – Retrofit2, RxJava2
Introduction of depend on
Implementation 'com. Squareup. Retrofit2: retrofit: 2.5.0' implementation 'com. Squareup. Retrofit2: converter - gson: 2.5.0' Implementation 'com. Squareup. Retrofit2: adapter - rxjava2:2.3.0' implementation 'IO. Reactivex. Rxjava2: rxandroid: 2.1.1' Implementation 'IO. Reactivex. Rxjava2: rxjava: 2.2.8'Copy the code
Define the interface
import java.util.Map; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FieldMap; import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.Query; Public interface RustDroneCommonService {/** ** @param content ** * @param content */ @formurlencoded @post ("feedbackAction") Observable<FeedbackResp> userFeedback(@field ("appVersion") String appVersion, @Field("phoneModel") String phoneModel, @Field("phoneOsVersion") String osVersion, @Field("submitContent") String content, @FieldMap Map<String, String> map); /** * GET mobile phone verification code ** @param Mobile phone number */ @get ("verifyCode") Observable<PhoneCodeResp> getPhoneCode(@query ("mobile") String mobile, @Query("oprType") int type); }Copy the code
Call interface
import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; RustDroneDataCenter.getCenter().getCommonService().userFeedback(BuildConfig.VERSION_NAME, Build.MODEL.replace(" ", "-"), Build.VERSION.RELEASE, fd, ext) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<FeedbackResp>() { @Override public void onSubscribe(Disposable d) { // LL.dn(TAG, "onSubscribe: " + d); } @Override public void onNext(FeedbackResp feedbackResp) { LL.dn(TAG, "onNext: " + feedbackResp); if (feedbackResp.getCode() == 0) { popSubmitSuccessDialog(); } else {ll. e(" failed to upload user feedback "); mPbLayout.setVisibility(View.GONE); popRetryDialog(); }} @override public void onError(Throwable e) {ll.e (" code: "+ e); mPbLayout.setVisibility(View.GONE); popRetryDialog(); } @Override public void onComplete() { mPbLayout.setVisibility(View.GONE); LL. Dn (TAG, "onComplete: upload complete "); }});Copy the code
OkHttp interview questions:
1. Briefly summarize OkHttp’s advantages
OkHttp is an excellent web request framework that Has been added to the Android source code by Google. The more popular Retrofit also uses OkHttp by default.
- Easy to use, easy to expand.
- Supports HTTP/2, allowing all requests to the same host to share the same socket connection.
- If HTTP/2 is not available, use connection pool reuse to reduce request latency.
- Support for GZIP, reducing download size.
- Cache processing is supported to avoid repeated requests.
- If your service has multiple IP addresses, OkHttp will try alternate addresses when the first connection fails.
- OkHttp also handles proxy server issues and SSL handshake failures.
2. Describe the main workflow of OKHTTP
Step 1: Create Request and OkHttpClicent objects, wrap Request as a Call object, and Call the enQueue () method to perform the asynchronous Request;
Enqueue (AsyncCall) and promoteAndExecute(). Enqueue (AsyncCall) has two functions: Add AsyncCall to the readyAsyncCalls queue, and set the connection counter to the same Host. PromoteAndExecute () is responsible for actually scheduling AsyncCall resources: Iterate over readyAsyncCalls and place the request into runningAsyncCalls if the queue size that is executing does not exceed 64 and the connection counter of the same Host does not exceed 5. It then iterates through runningAsyncCalls, executing each request one by one;
AsyncCall submits itself to the thread pool for execution as a task, and then finishes.
3. OkHttp Interceptor class
Interceptors are a powerful mechanism provided in Okhttp that enables network listening, requests, and response rewriting, retries, and so on.
- RetryAndFollowUpInterceptor: failed to retry and redirect the interceptor
- BridgeInterceptor: a BridgeInterceptor, an interceptor that handles some of the required request headers
- CacheInterceptor: a CacheInterceptor used to handle caches
- ConnectInterceptor: a connection interceptor that establishes available connections. It is the basic of the CallServerInterceptor
- CallServerInterceptor: The request server interceptor writes the HTTP request to the IO stream and reads the Response from the IO stream
4. Describe how to use OKHttp to initiate a network request.
The steps to initiate a web request using OKHttp are as follows:
- New OKHttpClient
- Create a Request object based on the requested URL
The parameters used during the Request are placed in the RequestBody of the Request object
- Create a Call object using the Request object
- Call.execute () for synchronous requests and call.enqueue for asynchronous requests
- Gets and parses the request execution result object Response
5. How do I use OKHttp to process cookies?
There are two ways to use OKHttp for Cookie processing:
The first is manual processing, where response.headers() is used to retrieve all headers, including Cookie information, from the Response object for the callback. At this point, we can save the Cookie locally and add the Cookie information to the header the next time we make a network request.
The second is to use the Cookjar provided by OKHttp as follows:
builder = new OkHttpClient.Builder();
builder.cookieJar(new CookieJar() {
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<String, List<Cookie>>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url.host(), cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
});
okHttpClient = builder.build();
Copy the code
SaveFromResponse () is executed when the server response is received, and the Cookie information can be saved. LoadForRequest () is executed when the network request is initiated, and the saved Cookie information can be added.
6. What are the optimizations of OkHttp for network requests and how are they implemented?
OKHttp has the following major improvements over native HttpUrlConnection:
- Support HTTP2 / SPDY
- The socket automatically selects the best route and supports automatic reconnection
- Automatic maintenance of the socket connection pool, reduce the number of handshakes, reduce the response delay
- Have a queue thread pool, easy to write concurrency
- Having Interceptors easily handle requests and responses (e.g. Transparent GZIP compression,LOGGING)
- Headers based caching strategy to avoid repeated network requests
Android development: framework source code parsing video reference