流程图
代码组织
我主要实现了一个 NetshowView 的Android 自定义视图,继承自 TextView。类中包含了两个内部类:NetworkConnectReceiver 和 SettingsValueChangeContentObserver 。
NetworkConnectReceiver 是一个广播接收器,用于监听网络连接状态的变化
SettingsValueChangeContentObserver 是一个内容观察者,用于监听系统设置中的 network_speed_yhk 配置变化。
功能实现
- 自定义视图主要用于显示网络接收速度。
- 当网络连接建立时,会开始监控并显示网络接收速度。
- 网络接收速度的计算逻辑位于静态方法 mshowNetSpeed()中,每秒更新一次。
- 使用了一个 ScheduledExecutorService 来定期执行网络速度的计算和展示任务。
- 通过 mNetReceiver 监听网络连接状态的变化,并根据网络是否连接来启动或停止速度监控。
- 通过 mContentObserver 监听 network speed yhk 设置的变化,以便在设置更改时启动或停止速度监控
消息处理
public class NetworkConnectReceiver extends BroadcastReceiver {
public NetworkConnectReceiver() {
}
@Override // android.content.BroadcastReceiver
public final void onReceive(Context context, Intent intent) {
NetworkInfo networkInfo;
if ("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction()) && (networkInfo = (NetworkInfo) intent.getParcelableExtra("networkInfo")) != null) {
boolean z = false;
if (NetworkInfo.State.CONNECTED == networkInfo.getState()) {
NetShowView.this.mIsConn = true;
if (Settings.Global.getInt(context.getContentResolver(), "network_speed_yhk", 0) == 1) {
z = true;
}
if (z) {
NetShowView.m69$$Nest$mstart(NetShowView.this);
} else {
NetShowView.m70$$Nest$mstop(NetShowView.this);
}
} else {
NetShowView netShowView = NetShowView.this;
netShowView.mIsConn = false;
NetShowView.m70$$Nest$mstop(netShowView);
}
}
if (intent.getAction().equals("com.android.yhk.send_network")) {
NetShowView.m68$$Nest$mshowNetSpeed(NetShowView.this);
}
}
}
这段代码是一个Java类,它继承自BroadcastReceiver类。这个类名为NetworkConnectReceiver,用来接收网络连接状态变化的通知。
NetworkConnectReceiver类有一个构造函数,但这个构造函数是空的,也就是说它什么也没做。
这个类重写了onReceive方法。当接收到广播时,这个方法会被调用。
- 首先,它检查广播的动作是否为"android.net.conn.CONNECTIVITY_CHANGE",并且尝试获取传递的NetworkInfo对象。
- 如果网络状态是CONNECTED,则设置NetShowView的mIsConn为true。然后检查是否开启了网络速度显示,如果开启了,调用mstart方法,否则调用mstop方法。
- 如果网络状态不是CONNECTED,则将NetShowView的mIsConn设置为false,并调用m70$ N e s t Nest Nestmstop方法来停止显示。
- 如果广播的动作是"com.android.yhk.send_network",则调用mshowNetSpeed方法来显示网络速度。
最终结果
package com.android.systemui.statusbar.phone;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.NetworkInfo;
import android.net.TrafficStats;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.AttributeSet;
import android.widget.TextView;
import com.android.systemui.R$styleable;
import com.android.systemui.plugins.DarkIconDispatcher;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/* loaded from: classes.dex */
public class NetShowView extends TextView implements DarkIconDispatcher.DarkReceiver {
public ScheduledExecutorService executorService;
public AnonymousClass1 handler;
public long lastTimeStamp;
public long lastTotalRxBytes;
public SettingsValueChangeContentObserver mContentOb;
public Context mContext;
public boolean mIsConn;
public NetworkConnectReceiver mNetReceiver;
public Paint mPaint;
public String mSpeed;
/* loaded from: classes.dex */
public class NetworkConnectReceiver extends BroadcastReceiver {
public NetworkConnectReceiver() {
}
@Override // android.content.BroadcastReceiver
public final void onReceive(Context context, Intent intent) {
NetworkInfo networkInfo;
if ("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction()) && (networkInfo = (NetworkInfo) intent.getParcelableExtra("networkInfo")) != null) {
boolean z = false;
if (NetworkInfo.State.CONNECTED == networkInfo.getState()) {
NetShowView.this.mIsConn = true;
if (Settings.Global.getInt(context.getContentResolver(), "network_speed_yhk", 0) == 1) {
z = true;
}
if (z) {
NetShowView.m69$$Nest$mstart(NetShowView.this);
} else {
NetShowView.m70$$Nest$mstop(NetShowView.this);
}
} else {
NetShowView netShowView = NetShowView.this;
netShowView.mIsConn = false;
NetShowView.m70$$Nest$mstop(netShowView);
}
}
if (intent.getAction().equals("com.android.yhk.send_network")) {
NetShowView.m68$$Nest$mshowNetSpeed(NetShowView.this);
}
}
}
/* loaded from: classes.dex */
public class SettingsValueChangeContentObserver extends ContentObserver {
public SettingsValueChangeContentObserver() {
super(new Handler());
}
@Override // android.database.ContentObserver
public final void onChange(boolean z) {
super.onChange(z);
NetShowView netShowView = NetShowView.this;
if (netShowView.mIsConn) {
if (Settings.Global.getInt(netShowView.mContext.getContentResolver(), "network_speed_yhk", 0) == 1) {
NetShowView.m69$$Nest$mstart(NetShowView.this);
} else {
NetShowView.m70$$Nest$mstop(NetShowView.this);
}
}
}
}
/* renamed from: -$$Nest$mstop reason: not valid java name */
public static void m70$$Nest$mstop(NetShowView netShowView) {
netShowView.mContext.stopService(new Intent(netShowView.mContext, NetSpeedService.class));
netShowView.setVisibility(8);
ScheduledExecutorService scheduledExecutorService = netShowView.executorService;
if (scheduledExecutorService != null) {
scheduledExecutorService.shutdown();
netShowView.executorService = null;
}
}
public static void m68$$Nest$mshowNetSpeed(NetShowView netShowView) {
netShowView.getClass();
long totalRxBytes = TrafficStats.getTotalRxBytes();
long currentTimeMillis = System.currentTimeMillis();
long j = currentTimeMillis - netShowView.lastTimeStamp;
if (j <= 0) {
netShowView.mSpeed = "0B/s";
} else {
long j2 = ((totalRxBytes - netShowView.lastTotalRxBytes) * 1000) / j;
if (j2 < 1000) {
netShowView.mSpeed = j2 + "B/s";
} else if (j2 < 1024000) {
String valueOf = String.valueOf(j2 % 1024);
long j3 = j2 / 1024;
if (valueOf.length() > 1) {
valueOf = valueOf.substring(0, 1);
}
netShowView.mSpeed = j3 + "." + valueOf + "K/s";
} else {
String valueOf2 = String.valueOf(j2 % 1048576);
long j4 = (j2 / 1024) / 1024;
if (valueOf2.length() > 1) {
valueOf2 = valueOf2.substring(0, 1);
}
netShowView.mSpeed = j4 + "." + valueOf2 + "M/s";
}
}
netShowView.lastTimeStamp = currentTimeMillis;
netShowView.lastTotalRxBytes = totalRxBytes;
netShowView.invalidate();
netShowView.handler.sendEmptyMessage(1);
}
/* renamed from: -$$Nest$mstart reason: not valid java name */
public static void m69$$Nest$mstart(NetShowView netShowView) {
netShowView.getClass();
netShowView.lastTotalRxBytes = TrafficStats.getTotalRxBytes();
netShowView.lastTimeStamp = System.currentTimeMillis();
new Thread(new Runnable() { // from class: com.android.systemui.statusbar.phone.NetShowView.2
@Override // java.lang.Runnable
public final void run() {
NetShowView netShowView2 = NetShowView.this;
if (netShowView2.executorService == null) {
netShowView2.executorService = Executors.newSingleThreadScheduledExecutor();
NetShowView.this.executorService = Executors.newScheduledThreadPool(1);
NetShowView.this.executorService.scheduleWithFixedDelay(new Runnable() { // from class: com.android.systemui.statusbar.phone.NetShowView.2.1
@Override // java.lang.Runnable
public final void run() {
NetShowView.m68$$Nest$mshowNetSpeed(NetShowView.this);
}
}, 1000L, 1500L, TimeUnit.MILLISECONDS);
}
}
}).start();
netShowView.setVisibility(0);
}
public NetShowView(Context context, AttributeSet attributeSet) {
super(context, attributeSet); // 调用父类的构造函数
this.lastTotalRxBytes = 0L; // 初始化网络接收字节数为0
this.lastTimeStamp = 0L; // 初始化最后的时间戳为0
this.mSpeed = ""; // 初始化网络速度字符串为空
this.executorService = null; // 初始化线程池为null
this.handler = new Handler() { // 创建一个Handler对象
@Override // 重写handleMessage方法
public final void handleMessage(Message message) {
NetShowView netShowView = NetShowView.this; // 获取当前NetShowView的引用
netShowView.setText(netShowView.mSpeed); // 设置视图的文本为网络速度
}
};
TypedArray obtainStyledAttributes = context.getTheme().obtainStyledAttributes(attributeSet, R$styleable.Clock, 0, 0); // 获取样式属性
try {
getCurrentTextColor(); // 获取当前文本颜色
obtainStyledAttributes.recycle(); // 回收TypedArray对象
this.mContext = context; // 将上下文保存为成员变量
Paint paint = new Paint(); // 创建一个Paint对象
this.mPaint = paint; // 将Paint对象保存为成员变量
paint.setAntiAlias(true); // 设置画笔的抗锯齿属性
this.mPaint.setColor(getCurrentTextColor()); // 设置画笔颜色为当前文本颜色
this.mPaint.setTextSize(getTextSize()); // 设置画笔大小为文本大小
new Rect(); // 创建一个Rect对象,但未使用
if (this.mContentOb == null) { // 检查内容观察者是否为null
this.mContentOb = new SettingsValueChangeContentObserver(); // 创建一个新的内容观察者
this.mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor("network_speed_yhk"), true, this.mContentOb); // 注册内容观察者
}
if (this.mNetReceiver == null) { // 检查网络接收器是否为null
this.mNetReceiver = new NetworkConnectReceiver(); // 创建一个新的网络连接接收器
IntentFilter intentFilter = new IntentFilter(); // 创建一个IntentFilter对象
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); // 添加网络连接变化的动作
intentFilter.addAction("com.android.yhk.send_network"); // 添加发送网络信息的动作
this.mContext.registerReceiver(this.mNetReceiver, intentFilter); // 注册接收器
}
} catch (Throwable th) {
obtainStyledAttributes.recycle(); // 回收TypedArray对象
throw th; // 重新抛出异常
}
}
该版本利用广播消息机制实现网速显示刷新,去除了广播消息机制,直接利用定时器线程实现网速显示刷新。
// set this to true when you want it to stop
boolean mStopHandler = false;
Runnable runnable = new Runnable() {
@Override
public void run() {
// complete calculations
if (!mStopHandler) {
mHandler.postDelayed(this, 1000); //runs every second
}
}
};
// begin task
mHandler.post(runnable);