如何优化Android异步请求服务器数据?

在互联网驱动的世界中,移动应用程序需要共享和接收来自其产品的后端(例如,来自数据库)以及来自第三方来源(如Facebook和Twitter)的信息,这些交互通常通过RESTful API进行。当请求数量增加时,这些请求的生成方式对于开发变得非常关键,因为获取数据的方式确实会影响应用程序的用户体验。

同步请求的行为在服务器响应之前保持空闲状态,同步请求会阻止接口增加计算时间并使移动应用程序无响应。于是就异步请求出现,当客户端向服务器发出请求时,服务器将请求分派给事件处理程序,注册回调并继续执行下一个请求,当响应可用时,将使用结果响应客户端。这是一种更好的方法,因为异步请求允许独立执行任务。

上图显示了两种编程方法在客户端 - 服务器模型中的不同之处。在Android中,UI线程(通常称为主线程)是基于与异步编程相同的原理。

Android UI工具包不是线程安全的,如果工作线程(执行进行网络调用的任务)更新Android UI工具包,则可能导致未定义和意外的行为,追踪这可能是困难且耗时的。单线程模型确保UI不会同时被不同的线程修改,因此,如果我们使用来自网络的图像更新ImageView,则工作线程将在单独的线程中执行网络操作,而ImageView将由UI线程更新,这可确保操作是线程安全的。UI线程提供必要的同步,它还有助于UI线程始终是非阻塞的,因为实际任务在工作线程的后台发生的。

总之,请遵循Android开发中的两个简单规则:

不应阻止UI线程。

不应从非UI工作线程直接更新UI工具包。

在Android应用如果您需要在用户与应用程序交互时在主线程之外执行工作,最好使用AsyncTask或Volley等网络库。

以下是使用AsyncTask实现异步工作线程的方法:

Subclass AsyncTask实现该onPreExecute()方法,它将创建一个toast消息,表明网络调用即将发生。

实施doInBackground(Params...)方法,顾名思义,doInBackground是工作线程进行网络调用并保持主线程免费。

由于工作线程无法直接更新UI,因此我实现了自己的postExecute(Result)方法,该方法将从网络调用中提供结果并在UI线程中运行,以便可以安全地修改用户界面。

后台任务的进度可以使用该publishProgress()方法从工作线程发布,并且可以使用该onProgressUpdate(Progress...)方法在UI线程上更新。

最后,使用execute()UI线程中的方法调用异步任务。

让我们进一步继续了解Volley:

Volley运行一个缓存处理线程和一个网络分派线程池。

网络调用请求首先由缓存线程进行分类。如果响应可以从缓存中提供,则缓存的响应将被解析CacheDispatche并传递回主线程UI线程。

如果结果在缓存中不可用,则需要进行网络请求以获取所需数据,请求将放入网络队列中。

第一个可用的网络线程(NetworkDispatcher)从队列中获取请求,然后,它执行HTTP请求,解析工作线程上的响应并将响应写入缓存。然后它将解析后的响应传递回主线程。

总结:

Android中的UI线程或主线程执行将事件分派给UI工具包的工作,并负责将消息队列中的请求出列以通知窗口小部件采取操作,这就是为什么UI线程始终是非阻塞的重要性。

Android有自己的HTTP客户端库,例如HttpURLConnection它可以帮助您执行同步网络调用。为了保持主线程不阻塞,需要在后台运行的工作线程中执行网络调用。

Android的AsyncTask库可以帮助在后台运行任务,并确保主线程是非阻塞的。它还确保后台任务不直接更新UI,相反,它将结果返回到UI线程。

AsyncTask有其局限性,例如无法缓存响应而无法处理并行请求,当后台任务运行时,它也不能正常处理屏幕旋转等场景。

使用Volley进行异步网络调用是开发Android应用程序的更简洁的解决方案,Volley拥有一系列强大的功能,例如缓存,请求取消和优先级排序。

Volley可以处理多种请求类型,例如JSON,图像和文本,并且它比AsyncTask表现更好。

提倡中国程序员分享精神,公众号(Software科技言)所有免费资料由自学IT爱好者提供,在此特别感谢!

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20181212A1MHL300?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券