Android SDK 网络模块解析,Android面试吃透这一篇就没有拿不到的offer

  1. 包含很多可能使用不到的功能以及冗余的代码,引入后会导致体积增大很多。

基于开源网络框架实现网络请求方案有利有弊,可以根据实际需要选择合适的开源网络框架。

2.2 基于系统方法


基于系统方法实现的网络请求方案通常采用 HttpURLConnection 或 HttpClient:

  • HttpURLConnection:在 JDK 的 java.net 包提供的一种多用途、轻量级的访问 HTTP 协议的基本功能类,大多数的应用程序都使用该接口进行网络访问请求;

  • HttpClient:是 Apache 开源组织提供的网络访问类,封装了 HTTP 协议的细节实现,Android 6.0 之前包含在系统 API 中。

它们都提供较多的 API,而且相对比较稳定。这两种网络请求类均有以下功能

  1. 支持 HTTPS 协议网络请求;

  2. 可以配置超时时间;

  3. 支持 IPv6 协议;

  4. 支持连接池;

  5. 可以实现流媒体的上传与下载。

在 Android 6.0 之前大多数应用的网络请求是通过 HttpClient 实现的,相比较于 HttpURLConnection ,使用 HttpClient 具有以下优势:

  1. 从易用性方面对比:HttpClient 封装了 HTTP 协议的细节,使用起来比较方便。HttpURLConnection 是 Java 的标准类,由于缺少封装导致使用不便;

  2. 从稳定性方面对比:HttpClient 功能强大且更稳定,容易控制细节。而之前的 HttpURLConnection 一直存在着版本兼容的问题。

从 Android 6.0 开始移除了 HttpClient,如果在 Android 6.0 以上继续使用 HttpClient 时,需要在相应的 module下的 build.gradle 中进行依赖库配置。具体配置如下:

android {

useLibrary ‘org.apache.http.legacy’

}

因此,Android 6.0 以上,更推荐使用 HttpURLConnection。从上述的分析可以看出:之前一直使用 HttpClient 是由于 HttpURLConnection 不稳定导致的。目前谷歌已经修复了 HttpURLConnection 存在的一些问题,相比 HttpClient 优势如表 2-1 所示:

表 2-1 HttpURLConnection 与 HttpClient 功能对比

因此,使用基于系统方法实现的网络请求方案一般采用 HttpURLConnection 来实现。

三、SDK 网络模块

============================================================================

如果 SDK 网络模块基于开源网络框架实现,可维护性和版本控制都有一定的风险,此外还会导致 SDK 体积增大很多。由于这些缺点很难被用户所接受,因此基于开源网络框架实现网络模块不适用于 SDK。

考虑到上述原因,SDK 网络模块最终采用了基于 HttpURLConnection 的方式实现。

HttpURLConnection 是系统提供的网络访问 API,不仅可满足 SDK 网络请求的需要,而且系统 API 功能更稳定,更易扩展。

3.1 原理介绍


3.1.1 实现原理

Android 中进行网络请求是基于 HTTP 协议实现的。HTTP 协议是目前 Internet 上最常使用、最重要的协议,该协议为典型的请求 - 响应模型:

  1. 客户端建立连接并发送请求;

  2. 服务端接受并处理请求;

  3. 服务端发送应答;

  4. 客户端接受并处理应答。

在基于 HttpURLConnection 实现网络请求方案时,很有必要对 HttpURLConnection 有进一步的了解。HttpURLConnection 继承自 URLConnection 抽象类,URLConnection 类本身依赖于 Socket 类实现网络连接。Socket 又称做套接字,它把复杂的网络操作抽象为简单的接口供上层调用。由于 HttpURLConnection 并不是底层的连接,而是在底层连接上的一个请求,因此 HttpURLConnection 不需要设置 Socket。

HttpURLConnection 支持 GET、POST、PUT、DELETE 等请求方式,最常用的就是 GET 与 POST 请求,下面从数据传输长度和安全性两方面对比:

  1. 数据传输长度:一般来说, GET 请求传输的数据长度有限制(URL 有长度限制),POST 请求传输的数据长度没有限制;

  2. 安全性:GET 请求安全性较差(发送的数据会拼接在 URL 后面),POST 请求相对安全(数据不显示在 URL 中)。

考虑到 SDK 采集的数据量相对较大,且对数据安全性要求较高,因此采用 HttpURLConnection POST 方式实现网络请求。

3.1.2 使用方式

HttpURLConnection 的具体使用步骤如图 3-1 所示:

图 3-1 HttpURLConnection 使用流程

由于涉及到网络访问,需要在 Manifest 文件添加网络访问权限:

以上是对 HttpURLConnection 的原理以及具体使用的介绍,下面对 SDK 中网络请求的具体实现进行介绍。

3.2 具体实现


3.2.1 网络相关配置

SDK 可以对数据上报进行一系列的配置,开发者可根据 App 的特点设置相应的配置,从而达到最高效的数据上报效果。SDK 的相关配置在初始化时完成,可以配置的参数如下:

mServerUrl:数据上报地址,采集的本地数据将上报到该地址; mFlushInterval:两次数据发送的最小时间间隔(单位毫秒),认值为 15; mFlushBulkSize:本地缓存数据的最大条目数,当本地缓存条数达到 mFlushBulkSize 则会上报数据, 认值为 100; mNetworkTypePolicy:网络上传策略,可配置为 3G、4G、5G、WIFI 等网络类型进行上报。

3.2.2 工作线程封装

SDK 数据上报是在子线程中完成的,当采集的数据满足上报策略时触发数据异步上报,上传任务的管理调度在 Worker 类中完成。在 Worker 初始化时,创建 HandlerThread 实例,HandlerThread 本质上是一个线程类,它继承自 Thread 类。HandlerThread 内有自己的 Looper 对象,可以进行 Looper 循环。通过获取 HandlerThread 中 Looper 对象传递给 Handler 对象,可以在 handleMessage 方法中执行异步任务。

AnalyticsMessageHandler 继承自 Handler,在 handleMessage 中接收 Worker 发送的消息并执行数据上报或删除

在 HandlerThread 中的 Looper 对象,传递给 AnalyticsMessageHandler 对象,在 handleMessage 方法中实现异步网络任务。AnalyticsMessageHandler 代码实现如下:

private class AnalyticsMessageHandler extends Handler {

Worker() {

final HandlerThread thread =

new HandlerThread(“com.sensorsdata.analytics.android.sdk.AnalyticsMessages.Worker”,

Thread.MIN_PRIORITY);

thread.start();

mHandler = new AnalyticsMessageHandler(thread.getLooper());

}

@Override

public void handleMessage(Message msg) {

if (msg.what == FLUSH_QUEUE) {

sendData();

} else if (msg.what == DELETE_ALL) {

try {

mDbAdapter.deleteallEvents();

} catch (Exception e) {

com.sensorsdata.analytics.android.sdk.SALog.printstacktrace(e);

}

} else {

SALog.i(TAG, "Unexpected message received by SensorsData worker: " + msg);

}

}

}

Worker 中封装了两个方法 runMessage 和 runMessageOnce :

  • runMessage 方法用于执行数据实时上报;

  • runMessageOnce 方法用于延时执行上报任务。

Handler 中的 sendMessageDelayed() 方法可以实现数据的延时上报。

3.2.3 数据上报策略

在 SDK 数据存储解析中介绍了数据的采集与存储策略:采集的数据会先保存到本地,符合上报策略才会上报。

  • 客户端本地存储的数据超过一定条数时(认 100 条)会上报数据

在 SDK 初始化时,可配置 mFlushBulkSize 参数来控制条数限制。如果不进行设置,则认为 100 条。如果用户设置的条数小于 50 条,则认为 50 条。SDK 采集的数据较多,如果设置上报条数太小会导致频繁的网络请求(上报数据),从而影响性能。如果用户设置上报条数过多,会导致一次上传的数据过大,这样不仅会导致上传时间长还很可能会出现上传失败的情况。如果没有特殊要求,可直接使用认值。

  • 数据采集后间隔一定时间(认 15 秒)会上报数据

在 SDK 初始化时,可配置 mFlushInterval 参数来控制时间间隔限制。如果不满足上报条数限制时,SDK 会执行一个延时任务,延时 mFlushInterval 设定的时间后执行

总结

首先是感觉自己的基础还是不够吧,大厂好像都喜欢问这些底层原理。

另外一部分原因在于资料也还没有看完,一面时凭借那份资料考前突击恶补个几天居然也能轻松应对(在这里还是要感谢那份资料,真的牛),于是自我感觉良好,资料就没有怎么深究下去了。

之前的准备只涉及了Java、Android、计网、数据结构与算法这些方面,面对面试官对其他基础课程的考察显得捉襟见肘。

下一步还是要查漏补缺,进行针对性复习。

最后的最后,那套资料这次一定要全部看完,是真的太全面了,各个知识点都涵盖了,几乎我面试遇到的所有问题的知识点这里面都有!在这里也免费分享给大家,希望大家不要犯和我一样的错误呀!!!一定要看完!


获取方式:点击我的GitHub

643775476906)]

[外链图片转存中…(img-wykUCeS7-1643775476907)]

[外链图片转存中…(img-AdXbUHxL-1643775476907)]
获取方式:点击我的GitHub

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...