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

CEIDCO: 2024 Global Electricity Development Index Research Report

Electricity is the core and key link in building ...

Can India become an exciting battlefield for Apple's "PUBG"?

Earlier this month, Apple launched its largest fr...

Sanxin Notes · Beginner's Guide, Copy and Paste, Earn 500+ Per Day

Recently, some friends have been asking me if the...

3 practical live streaming sales techniques!

Some people say that sales is a script, and all y...

What are the requirements for joining Douyin?

Juleliang Baiying, also known as Buy in, is a sce...

How to motivate users to continuously produce high-quality content

Zhihu original question: In addition to the more ...

Just bite me, why are you buzzing at me?

Review expert: Mo Jianchu, Professor of Institute...