Android Network--How I did it: Volley+OkHttp+Https

Android Network--How I did it: Volley+OkHttp+Https

Use OkHttp as the transport layer implementation.

By default, Volley uses different HTTP transport protocols according to the Android system version.
Volley uses ApacheHttpStack as the transport protocol on Android 3.0 and above, and HttpURLConnection as the transport layer protocol on 2.3 and below

OkHttp has the following advantages over other implementations.

  • Supports SPDY, allowing all requests connecting to the same host to share a socket.
  • If SPDY is not available, a connection pool is used to reduce request latency.
  • Downloads are compressed using GZIP, and the compression is transparent to the user.
  • Leverage response caching to avoid duplicate network requests.
  • When network problems occur, OKHttp will still work and it will recover from common connection problems.
  • If your server has multiple IP addresses, when the first address fails to connect, OKHttp will try to connect to other addresses. This is very necessary for IPV4 and IPV6 services and services hosted in multiple data centers.

Therefore, using OkHttp as an alternative is a good choice.

  1. head First, use OkHttp to implement a new HurlStack to build Volley's requestQueue.

    1. public   class OkHttpStack extends HurlStack {
    2.  
    3. private OkHttpClient okHttpClient;
    4.  
    5. /**
    6. * Create a OkHttpStack with default OkHttpClient.
    7. */  
    8. public OkHttpStack() {
    9. this ( new OkHttpClient());
    10. }
    11.  
    12. /**
    13. * Create a OkHttpStack with a custom OkHttpClient
    14. * @param okHttpClient Custom OkHttpClient, NonNull
    15. */  
    16. public OkHttpStack(OkHttpClient okHttpClient) {
    17. this .okHttpClient = okHttpClient;
    18. }
    19.  
    20. @Override  
    21. protected HttpURLConnection createConnection(URL url) throws IOException {
    22. OkUrlFactory okUrlFactory = new OkUrlFactory(okHttpClient);
    23. return okUrlFactory.open(url);
    24. }
    25. }
  2. Then use OkHttpStack to create a new Volley requestQueue.

    1. requestQueue = Volley.newRequestQueue(getContext(), new OkHttpStack());
    2. requestQueue.start();

    That's it.

Using Https

As a developer with integrity, you should use HTTPS to protect user data. The article Security with HTTPS and SSL on the Android Developers website explains this in detail.

OkHttp itself supports Https. Refer to the document OkHttp Https, and use the above OkHttpStack directly. However, if the server developer uses a self-signed certificate (don't ask me why I use a self-signed certificate), it will not be accessible normally.

Many articles on the Internet provide a solution that provides a TrustManager that does nothing and skips SSL verification. This is very vulnerable to attacks, and Https is useless.

The solution I adopted is to package the self-signed certificate into the APK and add trust.

benefit:

  • The application is difficult to reverse engineer. The application no longer relies on the system's trust store, making tools such as Charles packet capture ineffective. To analyze the application API, the APK must be decompiled.
  • No need to purchase additional certificates, save money....

shortcoming:

  • The flexibility of certificate deployment is reduced, and the program must be upgraded once the certificate is changed.

Implementation steps

Take the most famous self-signed website 12306 as an example

  1. Exporting a Certificate

    1. echo | openssl s_client -connect kyfw. 12306 .cn: 443   2 >& 1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > kyfw. 12306 .cn.pem
  2. Convert the certificate to bks format Download the latest bcprov-jdk and execute the following command. storepass is the password for exporting the key file.

    1. keytool -importcert -v \
    2. -trustcacerts \
    3. -alias 0 \
    4. -file <(openssl x509 -in kyfw. 12306 .cn.pem) \
    5. -keystore $CERTSTORE -storetype BKS \
    6. -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider \
    7. -providerpath ./bcprov-jdk16- 1.46 .jar \
    8. -storepass asdfqaz
  3. Put the exported kyfw.bks file into the res/raw folder.

  4. Create SelfSignSslOkHttpStack

    1. /**
    2. * A HttpStack implement witch can verify specified self-signed certification.
    3. */  
    4. public   class SelfSignSslOkHttpStack extends HurlStack {
    5.  
    6. private OkHttpClient okHttpClient;
    7.  
    8. private Map<String, SSLSocketFactory> socketFactoryMap;
    9.  
    10. /**
    11. * Create a OkHttpStack with default OkHttpClient.
    12. */  
    13. public SelfSignSslOkHttpStack(Map<String, SSLSocketFactory> factoryMap) {
    14. this ( new OkHttpClient(), factoryMap);
    15. }
    16.  
    17. /**
    18. * Create a OkHttpStack with a custom OkHttpClient
    19. * @param okHttpClient Custom OkHttpClient, NonNull
    20. */  
    21. public SelfSignSslOkHttpStack(OkHttpClient okHttpClient, Map<String, SSLSocketFactory> factoryMap) {
    22. this .okHttpClient = okHttpClient;
    23. this .socketFactoryMap = factoryMap;
    24. }
    25.  
    26. @Override  
    27. protected HttpURLConnection createConnection(URL url) throws IOException {
    28. if ( "https" .equals(url.getProtocol()) && socketFactoryMap.containsKey(url.getHost())) {
    29. HttpsURLConnection connection = (HttpsURLConnection) new OkUrlFactory(okHttpClient).open(url);
    30. connection.setSSLSocketFactory(socketFactoryMap.get(url.getHost()));
    31. return connection;
    32. } else {
    33. return    new OkUrlFactory(okHttpClient).open(url);
    34. }
    35. }
    36. }
  5. Then use SelfSignSslOkHttpStack to create Volley's RequestQueue.

    1. String[] hosts = { "kyfw.12306.cn" };
    2. int [] certRes = {R.raw.kyfw};
    3. String[] certPass = { "asdfqaz" };
    4. socketFactoryMap = new Hashtable<>(hosts.length);
    5.  
    6. for ( int i = 0 ; i < certRes.length; i++) {
    7. int res = certRes[i];
    8. String password = certPass[i];
    9. SSLSocketFactory sslSocketFactory = createSSLSocketFactory(context, res, password);
    10. socketFactoryMap.put(hosts[i], sslSocketFactory);
    11. }
    12.  
    13. HurlStack stack = new SelfSignSslOkHttpStack(socketFactoryMap);
    14.  
    15. requestQueue = Volley.newRequestQueue(context, stack);
    16. requestQueue.start();
  6. Let's try it out by replacing the original RequestQueue with the one created in the previous step and then sending a request.

    1. StringRequest request = new StringRequest(
    2. Request.Method.GET,
    3. "https://kyfw.12306.cn/otn/" ,
    4. new Response.Listener<String>() {
    5. @Override  
    6. public   void onResponse(String response) {
    7. responseContentTextView.setText(response);
    8. }
    9. },
    10. new Response.ErrorListener() {
    11. @Override  
    12. public   void onErrorResponse(VolleyError error) {
    13. responseContentTextView.setText(error.toString());
    14. }
    15. });
    16. RequestManager.getInstance( this ).addRequest(request, this );
  7. done

<<:  iOS Translucent Beginner's Guide to Teaching You How to Make It

>>:  Experience Introduction: Glow App Develops Apple Watch App

Recommend

Industrial robots, human assistants or anxiety-generating machines?

The rapid development of the Internet has made th...

How to increase website traffic? How to increase website traffic?

Increasing website traffic is the dream of every ...

Product strategy for traffic growth from 0 to 1!

As the traffic dividend has peaked and it becomes...

Advanced on-demand marketing techniques for video platforms!

Recently, the advanced on-demand broadcast of &qu...

CI build performance issues caused by upgrading JDK 11 on Feishu Android

Author: Qin Bingbing & Song Zhiyang I. Summar...

International Star Hotel Soft Decoration Design Course

International star hotel soft decoration design c...

What? Pigeons can play table tennis?

Pigeons are a symbol of peace and " keeping ...

Douyin live streaming sales - the secret of data

All apps have their own algorithms, including Zhi...

Introduce Gradle dependencies in Android projects like npm

[[206604]] 1. Introduction As an Android develope...

Event promotion: Improve the conversion rate of offline activities?

This article will use offline activity cases to a...