目前初学中,在研究android获取网络状态过程
麻烦找个会的帮忙解析,谢谢,有偿
是要研究网络过程源码吗
面试官想知道的是你对Android UI绘制流程的了解怎么样,在你自定义UI的时候是如何避免卡顿的。
那造成UI卡顿的无非是两个主要原因,第一个是UI太复杂,嵌套太多导致的,第二个是我们自定义的UI或者控件本身存在问题。
那所以我们可以从这两点出发去分析:
那这个时候我们站在绘制流程的角度去讲,会好很多
卡顿原因:
一. 布局Layout过于复杂,布局无法在16ms内完成渲染。
那这个时候我们可以从布局无法在16ms内完成渲染这个点去进行分析,卡顿的原因就是无法在规定的时候内完成渲染,那我们应该怎么去说呢?
比如说:我们布局渲染的一帧它是需要在16MS内完成的,假设16ms没有完成,那它会发生什么样的情况呢,那你可以告诉面试官。
假设现在有个布局,渲染花了20ms,它没有在16ms中完成渲染,那这个时候会出现什么问题呢。在UI绘制中有一个概念叫做vysnc(垂直同步信号量),
我们UI之所以能进行渲染,全是由它来通知的,vysnc它是用来同步渲染,让AppUI和SurfaceFlinger可以按硬件产生的VSync节奏进行工作。那我们刚刚
说到,绘制一帧,系统规定的时间是16ms,因为Android系统每隔16ms发出VSYNC信号通知渲染下一帧。现在我们遇到的情况是画了20ms才渲染完毕,
那这个时候当VSync通知画第二帧的时候,你第一帧还没有画完,
那就会继续延迟16ms,也就是说原本16ms完成的事情,现在画了32ms。那可能有很多同学会问,为什么是16ms,那是因为,16ms意味着1000/60hz,相当于60fps。这是因为人眼与大脑之间的协作无法感知超过60fps的画面更新,
16ms的渲染时间的话,人眼是无法察觉到的,就好比显示器,它也有一个帧率的概念,帧率越高,显示器越高级,看起来越舒服,或者玩游戏,当我们FPS很低的时候,
我们人眼就会感觉到像是在一帧一帧跳,这就是因为渲染的速度能被我们人眼所察觉。但现在我们如果32ms完成一帧的话,那1S就只有30多帧,所以我就能察觉到卡顿。
那这个问题我们说清楚了,解决方案是什么呢?
二.View频繁的触发measure,layout,onDraw导致measure,layout累计耗时过多及导致整个View频繁的重新渲染。
6. 尽量少调用requestLayout()。
7. 避免屏幕多次measure,layout,onDraw。
8. 避免在类似onDraw这样的方法中创建对象,因为它会迅速占用大量内存,引起频繁的GC甚至内存抖动
9. 为什么要少调用requestLayout() 因为requestLayout它会重新测量布局和绘制,但是有时候在我们实际的开发中是不需要重新测绘量布局只需要重新绘制就可以,
所以这个时候我们就不要去调用requestLayout()而是invalidate()
下载google的demo,然后进行调试源码会看的更清楚
问题答案由GPT-4Plus模型(语音)与博主程序员之梦@共同编写:
在Android中获取网络状态,主要有以下几种方式:
可以注册BroadcastReceiver监听ConnectivityManager.CONNECTIVITY_ACTION广播,在onReceive()方法中获取网络状态:
java
public class NetWorkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni != null && ni.isConnected()) {
// 网络已连接
} else {
// 网络未连接
}
}
}
可以通过ConnectivityManager的getActiveNetworkInfo()方法直接获取当前活动网络的状态:
java
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
// 网络已连接
} else {
// 网络未连接
}
Android 8.0(API 26)引入了NetworkCallback API,可以通过这个API监听网络状态变化:
java
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
NetworkCallback networkCallback = new NetworkCallback() {
@Override
public void onAvailable(Network network) {
// 网络已连接
}
@Override
public void onLost(Network network) {
// 网络断开连接
}
};
cm.registerNetworkCallback(builder.build(), networkCallback);
可以注册WifiManager.WIFI_STATE_CHANGED_ACTION的广播,在接收器中获取Wifi状态:
java
public class WifiStateChangedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
switch (wifiState) {
case WifiManager.WIFI_STATE_ENABLED:
// Wifi已开启
break;
case WifiManager.WIFI_STATE_DISABLED:
// Wifi已关闭
break;
}
}
}
希望能帮助您理解Android中获取网络状态的几种主要方式。