本篇文章我们来一起写一个最基本的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软件编程有所帮助。
问题内容: 我有ajax请求执行3个任务: 保存模型(数据库) 发电子邮件 提供成功或失败的消息。 因为此任务需要太多时间。用户可以等待长达20秒的响应(成功或失败的消息)。并且,如果用户关闭浏览器,则它停止在该用户当前处理的操作之一中。 这是糟糕的用户体验。 我希望用户将其数据提交给我的控制器,然后他将收到“成功或失败的消息”。并且该过程将完全在服务器端,并且它应该支持多个会话。 我怎样才能做到
本文向大家介绍Android基于OkHttpUtils网络请求的二次封装,包括了Android基于OkHttpUtils网络请求的二次封装的使用技巧和注意事项,需要的朋友参考一下 OkHttpUtils网络请求为什么进行二次封装? 1、减少代码量 2、后期换网络处理框架方便 二次封装的实现原理 1、将网络请求提取在一个方法中 2、对里面的可变参数,可以通过参数传递过去,也可以提供一个set方法传递
Mpx提供了网络请求库fetch,抹平了微信,阿里等平台请求参数及响应数据的差异;同时支持请求拦截器,请求取消等 使用说明 import mpx from '@mpxjs/core' import mpxFetch from '@mpxjs/fetch' mpx.use(mpxFetch) // 第一种访问形式 mpx.xfetch.fetch({ url: 'http://xxx.com' }
我正在Android系统中进行网络通信项目,但我的应用程序不起作用!经过一些调试,我发现每个网络请求都有来自系统的空响应。 我尝试了很多方法,例如:1)硬重启手机2)将所有网络权限添加到清单文件中 3)使用本地网络(我的手机作为服务器)4)让所有应用程序连接到网络:设置 但!什么也没发生... 这是我的类似问题链接,但在这个主题中没有答案:无法仅在我的Android应用程序中连接到互联网。连接in
本文向大家介绍Flutter 网络请求框架封装详解,包括了Flutter 网络请求框架封装详解的使用技巧和注意事项,需要的朋友参考一下 Flutter 请求网络的三种方式 flutter 请求网络的方式有三种,分别是 Dart 原生的网络请求 HttpClient、第三方网络请求 http以及 Flutter 中的 Dio。我们可以比较一下这三种网络请求方式,然后封装为我们方便请求网络的工具类。
类似于Ajax,QAP实现了Fetch功能,能够简单的异步的获取资源。 GET QN.fetch('http://121.42.141.44:8888', { body: '', method: 'GET', mode: 'same-origin', dataType: 'text', }) .then(response => { return respon