Android最基本的异步网络请求框架

 更新时间:2016年04月21日 15:06:15   作者:absfree  
这篇文章主要为大家详细介绍了Android最基本的异步网络请求框架,感兴趣的小伙伴们可以参考一下

 本篇文章我们来一起写一个最基本的Android异步网络请求框架,借此来了解下Android中网络请求的相关知识。由于个人水平有限,文中难免存在疏忽和谬误,希望大家可以指出,谢谢大家。

1. 同步网络请求

    以HTTP的GET请求为例,我们来介绍一下Android中一个基本的同步请求框架的实现。直接贴代码:

public class HttpUtils {
 public static byte[] get(String urlString) {
  HttpURLConnection urlConnection = null;
  try {
   URL url = new URL(urlString);
   urlConnection = (HttpURLConnection) url.openConnection();
   //设置请求方法
   urlConnection.setRequestMethod("GET");
   //设置超时时间
   urlConnection.setConnectTimeout(5000);
   urlConnection.setReadTimeout(3000);

   //获取响应的状态码
   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();
   }
  }
 }

} 

    相信以上的代码我们大家都不陌生,以上代码就实现了基本的同步网络请求功能,get 方法会返回一个byte[]数组,后续我们可以根据返回的相应类型(文本或图片)对这个字节数组作进一步处理。 

2. 异步网络请求

    通常一个异步HTTP GET请求是这样的:发出get方法的调用后,相关任务会在后台线程中自动执行,而我们在主线程中继续处理其他工作,它成功获取GET请求的响应时,就会回调onSuccess方法。最直接的写法通常如下所示:

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);
     }
    });
   }
  });
 }
} 

       其中,ResponseHandler接口的定义如下:

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

    我们可以看到,以上实现异步GET请求的代码很直截了当,然而存在着以下问题:每次请求时都会创建一个线程,这样当请求比较频繁的情况下会创建大量大线程,这样的话创建、销毁线程以及线程调度的开销会很大。而且Thread对象是一个匿名内部类对象,会隐式持有外围类引用,可能会引起Memory Leak。

    针对以上问题,我们可以使用线程池来复用线程,以避免不必要的创建及销毁线程的开销,改进后AsyncHttpUtils类的代码如下:

public class AsyncHttpUtils {
 //获取当前设备的CPU数
 public static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
 //核心池大小设为CPU数加1
 private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
 //设置线程池的最大大小
 private static final int MAX_POOL_SIZE = 2 * CPU_COUNT + 1;
 //存活时间
 private static final long KEEP_ALIVE = 5L;
 
 //创建线程池对象
 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());
  
  //创建一个新的请求任务
  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不为空表明请求成功,回调onSuccess方法
       responseHandler.onSuccess(result);
      }
     });
    }
   }
  };
  threadPoolExecutor.execute(requestRunnable);
 }
}

以上代码主要就是使用了线程池来达到线程的复用的目的,希望本文所述对大家学习Android软件编程有所帮助。

相关文章

  • Android动画之小球拟合动画实例

    Android动画之小球拟合动画实例

    这篇文章主要介绍了Android动画之小球拟合动画实例的相关资料,需要的朋友可以参考下
    2017-07-07
  • Android系统永不锁屏永不休眠的方法

    Android系统永不锁屏永不休眠的方法

    在进行Android系统开发的时候,有些特定的情况需要设置系统永不锁屏,永不休眠.本篇文章给大家介绍Android 永不锁屏,开机不锁屏,删除设置中休眠时间选项,需要的朋友一起学习吧
    2016-07-07
  • android从系统图库中取图片的实例代码

    android从系统图库中取图片的实例代码

    这篇文章主要介绍了android从系统图库中取图片的方法,涉及Android读取及选择图片等相关操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • Android自定义日历滑动控件

    Android自定义日历滑动控件

    这篇文章主要为大家详细介绍了Android自定义日历滑动控件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Android studio实现app登录界面

    Android studio实现app登录界面

    这篇文章主要为大家详细介绍了Android studio实现app登录界面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Android通过json向MySQL中读写数据的方法详解【写入篇】

    Android通过json向MySQL中读写数据的方法详解【写入篇】

    这篇文章主要介绍了Android通过json向MySQL中读写数据的方法,结合实例形式较为详细的分析了Android json类的定义、调用及php接收json数据并写入mysql的实现技巧,需要的朋友可以参考下
    2016-06-06
  • Eclipse搭建Android开发环境(安装ADT,Android4.4.2)

    Eclipse搭建Android开发环境(安装ADT,Android4.4.2)

    这篇文章主要介绍了Eclipse搭建Android开发环境(安装ADT,Android4.4.2),有兴趣的可以了解一下。
    2016-11-11
  • Android Universal ImageLoader 缓存图片

    Android Universal ImageLoader 缓存图片

    Universal Image Loader for Android的目的是为了实现异步的网络图片加载、缓存及显示,支持多线程异步加载,通过本文给大家介绍Android Universal ImageLoader缓存图片相关资料,涉及到imageloader缓存图片相关知识,对imageloader缓存图片相关知识感兴趣的朋友一起学习
    2016-01-01
  • android实现记住用户名和密码以及自动登录

    android实现记住用户名和密码以及自动登录

    这篇文章主要为大家详细介绍了android实现记住用户名和密码以及自动登录,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • Android启动模拟器报错解决方法

    Android启动模拟器报错解决方法

    本文将详细介绍Android模拟器报"Failed To Allocate memory 8"错误的解决办法,需要了解的朋友可以参考下
    2012-12-12

最新评论