网络相关知识

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。

目录

  • 一、导读
  • 二、概览
  • 三、相关工具
    • 3.1 network profiler/ Inspector
    • 3.2 抓包工具
    • 3.3 三方库 stetho
    • 3.4 通过 TrafficStats 来统计流量
    • 3.5 通过 NetworkStatsManager 来统计流量
  • 四、优化
  • 五、 推荐阅读

在这里插入图片描述

一、导读

我们继续总结学习基础知识,温故知新。

本文主要讲述网络优化相关的概念及思路。

HTTP即超文本传输协议(HyperText Transfer Protocol) 是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应(百度百科)。

二、概览

针对网络优化的维度比较多,可以从多方面入手,
比如流量使用情况(单位时间内流量消耗,用户网络类型,是否前后台等),
添加流量监控,最好从请求开始到结束的完整流程。
再比如网络请求的成功率、请求速度等等。

网络的测试,细节会比较多,我们要充分的进行线下测试,并进行多维度的模拟,如弱网、无网、网络切换等。
为了更精准的测试我们app的流量,可以在设置里面将其他app联网权限关闭。

对于线上用户监控,在客户端,也要多维度监控,尽可能多的获取信息,以便排查问题,要获取到接口的每一步详细信息,
如某个接口的dns解析时间,连接时间、请求时间,请求状态,网络包大小,网络状态等等,再配合用户日志系统,进行统一收集展示。

三、相关工具

3.1 network profiler/ Inspector

目前,网络性能剖析器仅支持 HttpURLConnection 和 OkHttp 网络连接库
在新包的android studio profiler上已经移除,在新的菜单中。
打开方式如下: View > Tool Windows > App Inspection

如下图所示:
在这里插入图片描述

这个工具会实时显示网络活动,包括发送、接受的数据及连接数、状态等。

使用方式大家自行学习吧,比较简单。
官网链接

3.2 抓包工具

要熟悉一些抓包工具,如
charles
fidder

工具的使用请自行学习。

3.3 三方库 stetho

stetho是facebook开发的一个开源库,Android应用通过引入stetho,可以在Chrome/Chromium浏览器监控查看网络请求、数据库、SharedPreferences、UI布局层级等.

chrome://inspect/

Stetho库的地址:

工具的使用请自行学习。

3.4 通过 TrafficStats 来统计流量

我们使用 android.net.TrafficStats 类 来统计流量,
这个类只在api 18 以上才有,用来统计手机重启以来的流量使用情况。

其实本身TrafficStats类也是读取Linux提供的文件对象系统类型的文本进行解析。
android.net.TrafficStats类中,提供了多种静态方法,可以直接调用获取,返回类型均为 long型,如果返回等于-1代表 UNSUPPORTED 当前设备不支持统计。

static long  getMobileRxBytes()    //获取通过Mobile连接收到的字节总数,不包含WiFi  
static long  getMobileRxPackets()  //获取Mobile连接收到的数据包总数  
static long  getMobileTxBytes()    //Mobile发送的总字节数  
static long  getMobileTxPackets()  //Mobile发送的总数据包数  
static long  getTotalRxBytes()     //获取总的接受字节数,包含Mobile和WiFi等  
static long  getTotalRxPackets()   //总的接受数据包数,包含Mobile和WiFi等  
static long  getTotalTxBytes()     //总的发送字节数,包含Mobile和WiFi等  
static long  getTotalTxPackets()   //发送的总数据包数,包含Mobile和WiFi等   
static long  getUidRxBytes(int uid)  //获取某个网络UID的 接受 字节数  
static long  getUidTxBytes(int uid)  //获取某个网络UID的 发送字节数  

我们可以间隔一段时间读取一下使用的流量,

    public void start() {uid = Process.myUid();thread = new HandlerThread("123");thread.start();handler = new Handler(thread.getLooper()) {@Overridepublic void handleMessage(@NonNull Message msg) {if (msg.what == 1) {// TODO:  比如计算一下差值handler.sendEmptyMessageDelayed(1, 5 * 60 * 1000);}}};handler.sendEmptyMessageDelayed(1, 5 * 60 * 1000);}

(1)无法获取应用的数据流量消耗
从文档中仅能获取到指定uid的流量,但无法区分不同网络类型下的消耗
(2)无法获取某个时间段内的流量消耗

3.5 通过 NetworkStatsManager 来统计流量

精准统计流量消耗的方法
可以获取指定时间间隔内的流量消耗。

NetworkCapabilities.TRANSPORT_WIFI

NetworkStatsManager networkStatsManager = (NetworkStatsManager) getSystemService(NETWORK_STATS_SERVICE);//查询 指定网络类型 在 某时间间隔内 的总的流量统计信息
NetworkStats.Bucket querySummaryForDevice(int networkType, String subscriberId, long startTime, long endTime)//查询某uid在 指定网络类型 和 时间间隔内 的流量统计信息
NetworkStats queryDetailsForUid(int networkType, String subscriberId, long startTime, long endTime, int uid)  //查询 指定网络类型 在 某时间间隔内 的详细的流量统计信息(包括每个uid)
NetworkStats queryDetails(int networkType, String subscriberId, long startTime, long endTime) 

需要添加权限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions"/>

使用

@RequiresApi(api = Build.VERSION_CODES.M)public static long getNetStats(@NonNull Context context, long startTime, long endTime, int netType) {// 接收的流量long netDataReceive = 0;// 发送的流量long netDataSend = 0;String subId = null;// 通过 service获取NetworkStatsManager manager = (NetworkStatsManager) context.getApplicationContext().getSystemService(Context.NETWORK_STATS_SERVICE);if (manager == null) {return 0;}NetworkStats networkStats = null;NetworkStats.Bucket bucket = new NetworkStats.Bucket();try {// //查询 指定网络类型,  在 某时间间隔内 的总的流量统计信息networkStats = manager.querySummary(netType, subId, startTime, endTime);} catch (Exception e) {e.printStackTrace();}//查询某应用(uid)的数据流量统计信息while (networkStats != null && networkStats.hasNextBucket()) {networkStats.getNextBucket(bucket);int uid = bucket.getUid();if (getAppUid(context) == uid) {// 接收的流量netDataReceive += bucket.getRxBytes();// 发送的流量netDataSend += bucket.getTxBytes();}}// 返回总流量, 这个量跟在设置里面看应该是差不多的return (netDataReceive + netDataSend);}

这个方式在线上排查问题还是有用的,比如我们可以获取用户昨天的流量消耗情况,这些信息一起写入用户行为日志中,进行辅助排查。

这个时候最好带上用户所处的状态,比如是否在前后台等等。

前后台流量消耗统计
当然,我们也可启用定时任务,如TrafficStats获取流量的方式,隔一段时间记录一次,并且区分前后台,然后统一上报。

网络请求流量优化

四、优化

在应用内使用网络的情况非常多,比如各种功能接口api,图片,日志等,那么我们要优化的话,可以从下面几个方面入手。

  • 数据缓存,一些不常用的数据进行网络缓存,设定过期时间。
  • 增量更新,根据版本进行更新。
  • 数据压缩,如gzip。
  • 图片处理,进行压缩

页面打不开、打开慢、图片加载不出来等等大部分都是由于网络加载慢,请求成功率低导致。
我们先来看下http请求的流程,
图片来源网络
在这里插入图片描述

dns被劫持,或者dns解析速度慢,都是导致网络慢,所以要防劫持,可以使用httpdns,绕过运营商域名解析,我们稍微解释下 httpdns,
HTTPDNS是面向多端应用(移动端APP,PC客户端应用)的域名解析服务,具有域名防劫持、精准调度、实时解析生效的特性。

其工作流程是这样的:图片来源于 阿里dns文章
在这里插入图片描述

使用httpdns可以降低平均访问时长,提高链接成功率,防止劫持。

尽量使用最新版的http协议,里面有很多的网络优化。

另外我们自己需要统计一下接口请求耗时,成功率,错误码等等,通过okhttp 的eventlistener就可以实现,如果是其他的网络链接,可自行调研。


public class OkHttpEventListener extends EventListener {@Overridepublic void callStart(Call call) {super.callStart(call);}@Overridepublic void dnsStart(Call call, String domainName) {super.dnsStart(call, domainName);}@Overridepublic void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {super.dnsEnd(call, domainName, inetAddressList);}@Overridepublic void responseBodyStart(Call call) {super.responseBodyStart(call);}@Overridepublic void responseBodyEnd(Call call, long byteCount) {super.responseBodyEnd(call, byteCount);}@Overridepublic void callEnd(Call call) {super.callEnd(call);}@Overridepublic void callFailed(Call call, IOException ioe) {super.callFailed(call, ioe);}...
}

我们可以看到,里面有很多的回调,在对应的方法里面计算时间差,就可以算出请求时间。

而对于图片监控来说, 如果使用的是 Fresco ,则直接可以使用sdk提供的方法来做监控,在内部有一个
com.facebook.imagepipeline.listener.RequestListener,类 ,可以监控到具体的每一步。
我们只需要在fresco初始化时,设置一个监听即可

ImagePipelineConfig config = ImagePipelineConfig.newBuilder(mContext).setRequestListeners(listenerset) // 设置监听.setRequestListener2s()           // 设置监听.build();Fresco.initialize(mContext,config);

通过接口,可以拿到成功失败及失败原因,

public interface RequestListener2 extends ProducerListener2 {void onRequestStart(ProducerContext producerContext);void onRequestSuccess(ProducerContext producerContext);void onRequestFailure(ProducerContext producerContext, Throwable throwable);void onRequestCancellation(ProducerContext producerContext);
}

如果是其他的图片加载库,可自行调研。

最后,针对服务端,需要做好网络容灾方案。

五、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

ddd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/653177.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gRPC 基本原理

基础知识 RPC的语义是远程过程调用&#xff08;Remote Procedure Call&#xff0c;RPC&#xff09;就是将一个服务调用封装在一个本地方法中&#xff0c;让调用者像使用本地方法一样调用服务&#xff0c;对其屏蔽实现细节。 RPC 会给对应的服务接口名生成一个代理类&#xff0c…

[docker] 关于docker的面试题

docker命名空间&#xff1f; docker与虚拟机的区别&#xff1f; 容器虚拟机所有容器共享宿主机的内核每个虚拟机都有独立的操作系统和内核通过namespace实现资源隔离&#xff0c;通过cgroup实现限制资源的最大使用量完全隔离。每个虚拟机都有独立的硬件资源秒级启动速度分钟级…

超越 Node.js:Bun 的创新与突破

1. Bun Bun 是一个全新的 JavaScript 运行时&#xff0c;类似于 Node.js 和 Deno&#xff0c;它专注于提供出色的性能和开发者体验。Bun 的一些特点包括&#xff1a; 快速的性能&#xff1a;Bun 旨在提供高性能&#xff0c;无论是启动时间、执行速度还是安装依赖包的速度。 兼…

使用小米手机

额&#xff0c;因为很久以前的华为荣耀手机&#xff08;虽然现在不是华为了&#xff09;退役了&#xff0c;所以使用了小米手机。 文章目录 小米手机和电脑互联 小米手机和电脑互联 这里我用的ubuntu 22.04 和Redmi note 13 pro。其实开始我也没想到&#xff0c;小米居然可以直…

【3.6数据库系统】数据库备份与恢复技术

目录 1.数据备份1.1备份方式1.2备份类型 2.数据库故障与恢复 1.数据备份 1.1备份方式 △冷备份也称为静态备份&#xff0c;别是将数据库正常关闭&#xff0c;在停止状态下&#xff0c;将数据库的文件全部备份(复制)下来。 △热备份也称为动态备份&#xff0c;是利用备份软件&a…

林浩然的哲学穿越之旅:从道家“道”到柏罗丁的“太一”

林浩然的哲学穿越之旅&#xff1a;从道家“道”到柏罗丁的“太一” Lin Haoran’s Philosophical Journey Across Time: From Dao in Daoism to Plotinus’s “The One” 在这个充满奇思妙想的故事里&#xff0c;我们的主角林浩然可不是个普通的家伙。他是当代的一位哲学侦探&a…

【Java面试】redis

目录 Redis 介绍Reids常用5种数据类型一个字符串类型的值能存储最大容量是多少&#xff1f;Redis 有哪些适合的场景&#xff1f;Redis的并发竞争问题如何解决?什么是缓存穿透&#xff1f;如何避免&#xff1f;什么是缓存雪崩&#xff1f;何如避免&#xff1f;Redis 中设置过期…

Flutter开发进阶之Canvas

Flutter开发进阶之Canvas 在Flutter开发中Canvas作为一个绘制2D图形的工具&#xff0c;提供了一系列绘图方法&#xff0c;可以用来绘制各种形状、线条、文本和图像等&#xff1b; Canvas对象是作为CustomPainter的子组件进行构建的&#xff1b; void paint(Canvas canvas, Si…

(M)unity受伤反弹以及死亡动画

受伤反弹 1.在人物控制脚本中添加受伤后速度将为0&#xff0c;并添加一个反弹的力 在刷新移动时&#xff0c;需要在没有受伤的状态 public bool isHurt; public float hurtForce; private void FixedUpdate() {if(!isHurt)Move(); }public void GetHurt(Transform attacker) …

策略者模式-C#实现

该实例基于WPF实现&#xff0c;直接上代码&#xff0c;下面为三层架构的代码。 目录 一 Model 二 View 三 ViewModel 一 Model using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 设计模式练…

探索元宇宙的未来:数字人对话系统 - Linly-Talker —— “数字人交互,与虚拟的自己互动”

探索元宇宙的未来&#xff1a;数字人对话系统 - Linly-Talker —— “数字人交互&#xff0c;与虚拟的自己互动” 之前空闲的时候我似乎已经写过了有关于数字人的两篇文章&#xff0c;今天更多的写这篇文章就是想探索一下元宇宙的未来&#xff0c;这种数字人对话系统能做什么&…

Unity - gamma space下还原linear space效果

文章目录 环境目的环境问题实践结果处理要点处理细节【OnPostProcessTexture 实现 sRGB 2 Linear 编码】 - 预处理【封装个简单的 *.cginc】 - shader runtime【shader需要gamma space下还原记得 #define _RECOVERY_LINEAR_IN_GAMMA】【颜色参数应用前 和 颜色贴图采样后】【灯…

【UE5】如何给人物骨骼绑定Control Rig用来制作动画(控制)

本篇文章暂时只教绑定人物手部的Control Rig&#xff0c;脚的Control Rig举一反三即可 1&#xff0c;右键-创建-控制绑定 2在控制绑定中-右键创建基本IK 3&#xff0c;填入上臂-下臂-手 4【手和下臂】右键-新建-Add Controls For Selected&#xff0c;&#xff08;或者新建-…

第十四章 RabbitMQ应用

文章目录 前言1、RabbitMQ概念1.1、生产者和消费者1.2、队列1.3、交换机、路由键、绑定1.3.1、交换机类型 2、RabbitMQ运转流程2.1、生产者发送消息流程2.2、消费者接收消息的过程2.3、AMQP协议 3、RabbitMQ windows安装3.1、下载3.2、安装 4、Spring Boot 整合RabbitMQ4.1、在…

【语录】岁月

中年 写中年&#xff0c;应该是年少励志三千里 踌躇百步无寸功&#xff0c;转眼高堂已白发 儿女蹒跚学堂中&#xff0c;不如意事常八九&#xff0c;可与人言无二三 可是诸位&#xff0c;不用悲伤&#xff0c;稻盛和夫说&#xff0c; 人生并不是一场物质的盛宴&#xff0c;而是…

单片机学习笔记---LCD1602调试工具

LCD1602调试工具 这一节开始之前先说明一下&#xff0c;模块化编程相关的知识&#xff08;就是将代码分成多个文件来写&#xff0c;比如函数的定义放在.c文件中&#xff0c;函数的声明写在.h文件中&#xff09;属于是C语言的内容&#xff0c;学过C语言的伙伴应该都知道。由于这…

Vue2.0+Element实现日历组件

(壹)博主介绍 &#x1f320;个人博客&#xff1a; 尔滨三皮⌛程序寄语&#xff1a;木秀于林&#xff0c;风必摧之&#xff1b;行高于人&#xff0c;众必非之。 (贰)文章内容 1、安装依赖 npm install moment2.29.4 --savenpm install lunar0.0.3 --savenpm install lunar-java…

配置华为交换机生成树VBST案例

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系 厦门微思网络​​​​​​https://www.xmws.cn 华为认证\华为HCIA-Datacom\华为HCIP-Datacom\华为HCIE-Datacom 思科认证CCNA\CCNP\CCIE 红帽认证Linux\RHCE\RHC…

代理IP使用指南:风险与注意事项

在当今的数字化时代&#xff0c;使用在线代理IP已经成为一种常见的网络行为。然而&#xff0c;在使用这些代理IP时&#xff0c;我们需要注意一些风险和问题&#xff0c;以确保我们的网络安全和隐本私文。将探讨使用代理IP时需要注意的几个关键问题。 1、代理IP的安全性 使用代理…

设计模式:工厂方法模式

工厂模式属于创建型模式&#xff0c;也被称为多态工厂模式&#xff0c;它在创建对象时提供了一种封装机制&#xff0c;将实际创建对象的代码与使用代码分离&#xff0c;有子类决定要实例化的产品是哪一个&#xff0c;把产品的实例化推迟到子类。 使用场景 重复代码 : 创建对象…