The most basic asynchronous network request framework of Android

  • 2021-07-06 11:48:33
  • OfStack

In this article, we will write a basic Android asynchronous network request framework, so as to understand the related knowledge of network request in Android. Due to the limited personal level, it is inevitable that there are negligence and fallacies in the text. I hope you can point out that thank you.

1. Synchronize network requests

Taking GET request of HTTP as an example, we will introduce the implementation of a basic synchronous request framework in Android under 1. Stick the code directly:


public class HttpUtils {
 public static byte[] get(String urlString) {
  HttpURLConnection urlConnection = null;
  try {
   URL url = new URL(urlString);
   urlConnection = (HttpURLConnection) url.openConnection();
   // Set the request method 
   urlConnection.setRequestMethod("GET");
   // Set timeout time 
   urlConnection.setConnectTimeout(5000);
   urlConnection.setReadTimeout(3000);

   // Gets the status code of the response 
   int responseCode = urlConnection.getResponseCode();
   if (responseCode == 200) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    InputStream in = urlConnection.getInputStream();
    byte[] buffer = new byte[4 * 1024];
    int len = -1;
    while((len = in.read(buffer)) != -1) {
     bos.write(buffer, 0, len);
    }
    close(in);
    byte[] result = bos.toByteArray();
    close(bos);
    return result;
   } else {
    return null;
   }
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (urlConnection != null) {
    urlConnection.disconnect();
   }
  }

  return null;
 }

 private static void close(Closeable stream) {
  if (stream != null) {
   try {
    stream.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

} 

I believe all of us are familiar with the above code, and the above code realizes the basic synchronous network request function. The get method will return an byte [] array, and then we can make a further step on this byte array according to the corresponding type (text or picture) returned.

2. Asynchronous network requests

Usually, an asynchronous HTTP GET request is like this: After the call of get method is made, the related task will be automatically executed in the background thread, while we continue to deal with other work in the main thread. When it successfully obtains the response of GET request, it will call back the onSuccess method. The most direct writing is usually as follows:


public class AsyncHttpUtils {public static byte[] get(String url, ResponseHandler handler) {
  final Handler mHandler = new Handler();
  new Thread(new Runnable() {
   @Override
   public void run() {
    final byte[] result = HttpUtils.get(url);
    handler.post(new Runnable() {
     @Override
     public void run() {
      responseHandler.onSuccess(result);
     }
    });
   }
  });
 }
} 

The ResponseHandler interface is defined as follows:


public interface ResponseHandler {
 void onSucess(bytep[] result);
}
 

We can see that the above code for implementing asynchronous GET request is very straightforward, but there are the following problems: 1 thread will be created every time a request is made, so a large number of large threads will be created when requests are frequent, so the overhead of creating, destroying threads and scheduling threads will be very large. Moreover, the Thread object is an anonymous inner class object, which implicitly holds a peripheral class reference, which may cause Memory Leak.

To solve the above problems, we can use thread pool to reuse threads to avoid unnecessary overhead of creating and destroying threads. The code of the improved AsyncHttpUtils class is as follows:


public class AsyncHttpUtils {
 // Object for the current device CPU Number 
 public static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
 // The core pool size is set to CPU Number addition 1
 private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
 // Set the maximum size of the thread pool 
 private static final int MAX_POOL_SIZE = 2 * CPU_COUNT + 1;
 // Survival time 
 private static final long KEEP_ALIVE = 5L;
 
 // Create a thread pool object 
 public static final Executor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
   MAX_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

 public static void get(final String url, final ResponseHandler responseHandler) {
  final Handler mHandler = new Handler(Looper.getMainLooper());
  
  // Create 1 New Request Tasks 
  Runnable requestRunnable = new Runnable() {
   @Override
   public void run() {
    final byte[] result = HttpUtils.get(url);
    if (result != null) {
     mHandler.post(new Runnable() {
      @Override
      public void run() {
       //result If it is not null, the request is successful, and the callback onSuccess Method 
       responseHandler.onSuccess(result);
      }
     });
    }
   }
  };
  threadPoolExecutor.execute(requestRunnable);
 }
}

The above code mainly uses thread pool to achieve the purpose of thread reuse. I hope this article is helpful for everyone to learn Android software programming.


Related articles: