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

The earliest known gibbon turned out to be this...

Ancient Discovery: The earliest known gibbon, it ...

Is H5 really becoming popular?

A few days ago, I saw a friend in the Internet ci...

TV games can also be played like this. LeTV game console brings arcade pleasure

Speaking of fighting games, if you tell me that y...

Marketing node reminder in May

April is coming to an end and May is approaching....

Ibuprofen is banned? Attention! These 223 drugs are no longer produced or sold

Expert of this article: Zhang Xing, deputy chief ...

He may be the world's first Apple iPhone 6s user

Thanks to the International Date Line, the first ...

What are the SEO marketing methods?

As the saying goes, "Even good wine needs to...