Android BatteryManager的使用及BatteryService源码分析

当需要监控系统电量时,用 BatteryManager 来实现。

参考官网 监控电池电量和充电状态

获取电池信息

通过监听 Intent.ACTION_BATTERY_CHANGED 广播实现,在广播接收器中获取电池信息。

这是个粘性广播,即使过了广播发出的时间点后再注册广播接收器,也可以收到上一个广播消息。

按照我的 Demo ,没有触发电量变化,直接打开这个页面就可以收到广播。

public class BatteryActivity extends AppCompatActivity {private final static String TAG = BatteryActivity.class.getSimpleName();private BatteryReceiver receiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_battery);Objects.requireNonNull(getSupportActionBar()).setTitle(TAG);receiver = new BatteryReceiver();IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_BATTERY_CHANGED);registerReceiver(receiver, filter);}@Overrideprotected void onStop() {super.onStop();unregisterReceiver(receiver);}private static class BatteryReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);int temperature =  intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);int status  = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0);int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 0);int pluggen = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);}}}
}

电量

电量百分比 = 当前电量 / 电池总量

int level =  intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
int batteryPct = level * 100 / scale;

电池温度

模拟器获取的值是 250

int temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);

电池健康

int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 0);

使用模拟器测试,
在这里插入图片描述
得到

电池健康
Unknown1
Good2
Overheat3
Dead4
Overvoltage5
Failed6

看 BatteryManager 源码,

	import android.hardware.health.V1_0.Constants;// values for "health" field in the ACTION_BATTERY_CHANGED Intentpublic static final int BATTERY_HEALTH_UNKNOWN = Constants.BATTERY_HEALTH_UNKNOWN; //1public static final int BATTERY_HEALTH_GOOD = Constants.BATTERY_HEALTH_GOOD; //2public static final int BATTERY_HEALTH_OVERHEAT = Constants.BATTERY_HEALTH_OVERHEAT; //3public static final int BATTERY_HEALTH_DEAD = Constants.BATTERY_HEALTH_DEAD; //4public static final int BATTERY_HEALTH_OVER_VOLTAGE = Constants.BATTERY_HEALTH_OVER_VOLTAGE; // 5public static final int BATTERY_HEALTH_UNSPECIFIED_FAILURE = Constants.BATTERY_HEALTH_UNSPECIFIED_FAILURE; //6public static final int BATTERY_HEALTH_COLD = Constants.BATTERY_HEALTH_COLD; // 7

追踪到 frameworks/native/services/batteryservice/include/batteryservice/BatteryServiceConstants.h

enum {BATTERY_STATUS_UNKNOWN = 1,BATTERY_STATUS_CHARGING = 2,BATTERY_STATUS_DISCHARGING = 3,BATTERY_STATUS_NOT_CHARGING = 4,BATTERY_STATUS_FULL = 5,
};enum {BATTERY_HEALTH_UNKNOWN = 1,BATTERY_HEALTH_GOOD = 2,BATTERY_HEALTH_OVERHEAT = 3,BATTERY_HEALTH_DEAD = 4,BATTERY_HEALTH_OVER_VOLTAGE = 5,BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6,BATTERY_HEALTH_COLD = 7,
};

电池状态 & 充电类型

电池状态

判断是否在充电,

int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0);

看 BatteryManager 源码,

	// values for "status" field in the ACTION_BATTERY_CHANGED Intentpublic static final int BATTERY_STATUS_UNKNOWN = Constants.BATTERY_STATUS_UNKNOWN;//1public static final int BATTERY_STATUS_CHARGING = Constants.BATTERY_STATUS_CHARGING;//2public static final int BATTERY_STATUS_DISCHARGING = Constants.BATTERY_STATUS_DISCHARGING;//3public static final int BATTERY_STATUS_NOT_CHARGING = Constants.BATTERY_STATUS_NOT_CHARGING;//4public static final int BATTERY_STATUS_FULL = Constants.BATTERY_STATUS_FULL;//5

充电类型

判断充电类型, 交流电、USB充电、无线充电。

int pluggen = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);

模拟器测试,None = 0 ,AC charger = 1 。

看 BatteryManager 源码,

	// values of the "plugged" field in the ACTION_BATTERY_CHANGED intent.// These must be powers of 2./** Power source is an AC charger. */public static final int BATTERY_PLUGGED_AC = OsProtoEnums.BATTERY_PLUGGED_AC; // = 1/** Power source is a USB port. */public static final int BATTERY_PLUGGED_USB = OsProtoEnums.BATTERY_PLUGGED_USB; // = 2/** Power source is wireless. */public static final int BATTERY_PLUGGED_WIRELESS = OsProtoEnums.BATTERY_PLUGGED_WIRELESS; // = 4

监听低电量

当电池点亮过低、电池电量充足会发出这两个广播。

按照官方建议,在电量低时应停用所有后台更新,此时应用应尽量避免进行后台操作。

	/*** Broadcast Action:  Indicates low battery condition on the device.* This broadcast corresponds to the "Low battery warning" system dialog.** <p class="note">This is a protected intent that can only be sent* by the system.*/@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)public static final String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";/*** Broadcast Action:  Indicates the battery is now okay after being low.* This will be sent after {@link #ACTION_BATTERY_LOW} once the battery has* gone back up to an okay state.** <p class="note">This is a protected intent that can only be sent* by the system.*/@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)public static final String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";

按照官网静态广播的写法,没有接收到 ,

		<receiverandroid:name=".battery.BatteryReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.intent.action.BATTERY_LOW"/><action android:name="android.intent.action.BATTERY_OKAY"/></intent-filter></receiver>

用动态广播的写法可以接收到,

receiver = new BatteryReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_BATTERY_LOW);
filter.addAction(Intent.ACTION_BATTERY_OKAY);
registerReceiver(receiver, filter);

用模拟器测试 ,
电量 15% 触发 Intent.ACTION_BATTERY_LOW ,电量 20% 触发 Intent.ACTION_BATTERY_OKAY

BatteryService源码分析

基于安卓11。

源码在 frameworks/base/services/core/java/com/android/server/BatteryService.java

对应的阈值都是定义在 frameworks$/base/core/res/res/values/config.xml , 厂商如需定制就改这里。

初始化

BatteryService 继承 SystemService ,

构造函数中

  • 初始化 Handler ;
  • 通过 LightsManager 实例化 Led ;
  • 获取各个阈值;
  • 监测 invalid_charger 。

onStart() 中

  • 注册电池健康回调,收到回调消息会调用 update(android.hardware.health.V2_1.HealthInfo info) 方法更新电池信息;
  • 初始化 BatteryPropertiesRegistrar 、BinderService 、LocalService。

onBootPhase(int phase) 中

  • 监听 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL 的变化,有变化时调用 updateBatteryWarningLevelLocked() 方法更新一次电池信息。
  • 调用 updateBatteryWarningLevelLocked() 方法更新一次电池信息。
public final class BatteryService extends SystemService {//...public BatteryService(Context context) {super(context);mContext = context;mHandler = new Handler(true /*async*/);mLed = new Led(context, getLocalService(LightsManager.class));mBatteryStats = BatteryStatsService.getService();mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);mCriticalBatteryLevel = mContext.getResources().getInteger(com.android.internal.R.integer.config_criticalBatteryWarningLevel);mLowBatteryWarningLevel = mContext.getResources().getInteger(com.android.internal.R.integer.config_lowBatteryWarningLevel);mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(com.android.internal.R.integer.config_lowBatteryCloseWarningBump);mShutdownBatteryTemperature = mContext.getResources().getInteger(com.android.internal.R.integer.config_shutdownBatteryTemperature);mBatteryLevelsEventQueue = new ArrayDeque<>();mMetricsLogger = new MetricsLogger();// watch for invalid charger messages if the invalid_charger switch existsif (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {UEventObserver invalidChargerObserver = new UEventObserver() {@Overridepublic void onUEvent(UEvent event) {final int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0;synchronized (mLock) {if (mInvalidCharger != invalidCharger) {mInvalidCharger = invalidCharger;}}}};invalidChargerObserver.startObserving("DEVPATH=/devices/virtual/switch/invalid_charger");}}//...@Overridepublic void onStart() {registerHealthCallback();mBinderService = new BinderService();publishBinderService("battery", mBinderService);mBatteryPropertiesRegistrar = new BatteryPropertiesRegistrar();publishBinderService("batteryproperties", mBatteryPropertiesRegistrar);publishLocalService(BatteryManagerInternal.class, new LocalService());}@Overridepublic void onBootPhase(int phase) {if (phase == PHASE_ACTIVITY_MANAGER_READY) {// check our power situation now that it is safe to display the shutdown dialog.synchronized (mLock) {ContentObserver obs = new ContentObserver(mHandler) {@Overridepublic void onChange(boolean selfChange) {synchronized (mLock) {updateBatteryWarningLevelLocked();}}};final ContentResolver resolver = mContext.getContentResolver();resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),false, obs, UserHandle.USER_ALL);updateBatteryWarningLevelLocked();}}}//...private void updateBatteryWarningLevelLocked() {final ContentResolver resolver = mContext.getContentResolver();int defWarnLevel = mContext.getResources().getInteger(com.android.internal.R.integer.config_lowBatteryWarningLevel);mLowBatteryWarningLevel = Settings.Global.getInt(resolver,Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);if (mLowBatteryWarningLevel == 0) {mLowBatteryWarningLevel = defWarnLevel;}if (mLowBatteryWarningLevel < mCriticalBatteryLevel) {mLowBatteryWarningLevel = mCriticalBatteryLevel;}mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(com.android.internal.R.integer.config_lowBatteryCloseWarningBump);processValuesLocked(true);}private void processValuesLocked(boolean force) {//...shutdownIfNoPowerLocked();shutdownIfOverTempLocked();// ...if (force || (mHealthInfo.batteryStatus != mLastBatteryStatus ||mHealthInfo.batteryHealth != mLastBatteryHealth ||mHealthInfo.batteryPresent != mLastBatteryPresent ||mHealthInfo.batteryLevel != mLastBatteryLevel ||mPlugType != mLastPlugType ||mHealthInfo.batteryVoltage != mLastBatteryVoltage ||mHealthInfo.batteryTemperature != mLastBatteryTemperature ||mHealthInfo.maxChargingCurrent != mLastMaxChargingCurrent ||mHealthInfo.maxChargingVoltage != mLastMaxChargingVoltage ||mHealthInfo.batteryChargeCounter != mLastChargeCounter ||mInvalidCharger != mLastInvalidCharger)) {// ...mLastBatteryStatus = mHealthInfo.batteryStatus;mLastBatteryHealth = mHealthInfo.batteryHealth;mLastBatteryPresent = mHealthInfo.batteryPresent;mLastBatteryLevel = mHealthInfo.batteryLevel;mLastPlugType = mPlugType;mLastBatteryVoltage = mHealthInfo.batteryVoltage;mLastBatteryTemperature = mHealthInfo.batteryTemperature;mLastMaxChargingCurrent = mHealthInfo.maxChargingCurrent;mLastMaxChargingVoltage = mHealthInfo.maxChargingVoltage;mLastChargeCounter = mHealthInfo.batteryChargeCounter;mLastBatteryLevelCritical = mBatteryLevelCritical;mLastInvalidCharger = mInvalidCharger;}}
}

低电量广播

电量 15% 触发 Intent.ACTION_BATTERY_LOW ,电量 20% 触发 Intent.ACTION_BATTERY_OKAY

<integer name="config_lowBatteryWarningLevel">15</integer>
<integer name="config_lowBatteryCloseWarningBump">5</integer>

逻辑很清楚,

当电量低于 mLowBatteryWarningLevel 就发出广播 Intent.ACTION_BATTERY_LOW

当电量高于 mLowBatteryCloseWarningLevel 就发出广播 Intent.ACTION_BATTERY_OKAY

	private int mLowBatteryWarningLevel;private int mLowBatteryCloseWarningLevel;// ...public BatteryService(Context context) {// ...mLowBatteryWarningLevel = mContext.getResources().getInteger(com.android.internal.R.integer.config_lowBatteryWarningLevel);mLowBatteryCloseWarningLevel = mLowBatteryWarningLevel + mContext.getResources().getInteger(com.android.internal.R.integer.config_lowBatteryCloseWarningBump);// ...}// ...if (shouldSendBatteryLowLocked()) {mSentLowBatteryBroadcast = true;final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);mHandler.post(new Runnable() {@Overridepublic void run() {mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);}});} else if (mSentLowBatteryBroadcast &&mHealthInfo.batteryLevel >= mLowBatteryCloseWarningLevel) {mSentLowBatteryBroadcast = false;final Intent statusIntent = new Intent(Intent.ACTION_BATTERY_OKAY);statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);statusIntent.putExtra(BatteryManager.EXTRA_SEQUENCE, mSequence);mHandler.post(new Runnable() {@Overridepublic void run() {mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);}});}// ...private boolean shouldSendBatteryLowLocked() {final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;/* The ACTION_BATTERY_LOW broadcast is sent in these situations:* - is just un-plugged (previously was plugged) and battery level is*   less than or equal to WARNING, or* - is not plugged and battery level falls to WARNING boundary*   (becomes <= mLowBatteryWarningLevel).*/return !plugged&& mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN&& mHealthInfo.batteryLevel <= mLowBatteryWarningLevel&& (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);}

超低电量关机

BatteryService.java 里,

	//...shutdownIfNoPowerLocked();// ...private boolean shouldShutdownLocked() {if (mHealthInfo2p1.batteryCapacityLevel != BatteryCapacityLevel.UNSUPPORTED) {return (mHealthInfo2p1.batteryCapacityLevel == BatteryCapacityLevel.CRITICAL);}if (mHealthInfo.batteryLevel > 0) {return false;}// Battery-less devices should not shutdown.if (!mHealthInfo.batteryPresent) {return false;}// If battery state is not CHARGING, shutdown.// - If battery present and state == unknown, this is an unexpected error state.// - If level <= 0 and state == full, this is also an unexpected state// - All other states (NOT_CHARGING, DISCHARGING) means it is not charging.return mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_CHARGING;}private void shutdownIfNoPowerLocked() {// shut down gracefully if our battery is critically low and we are not powered.// wait until the system has booted before attempting to display the shutdown dialog.if (shouldShutdownLocked()) {mHandler.post(new Runnable() {@Overridepublic void run() {if (mActivityManagerInternal.isSystemReady()) {Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);intent.putExtra(Intent.EXTRA_REASON,PowerManager.SHUTDOWN_LOW_BATTERY);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mContext.startActivityAsUser(intent, UserHandle.CURRENT);}}});}}

电量过低时发出 Intent.ACTION_REQUEST_SHUTDOWN 广播,

frameworks/base/core/java/com/android/internal/app/ShutdownActivity.java 处理广播

frameworks/base/core/res/AndroidManifest.xml

	<activity android:name="com.android.internal.app.ShutdownActivity"android:permission="android.permission.SHUTDOWN"android:theme="@style/Theme.NoDisplay"android:excludeFromRecents="true"><intent-filter><action android:name="com.android.internal.intent.action.REQUEST_SHUTDOWN" /><category android:name="android.intent.category.DEFAULT" /></intent-filter><intent-filter><action android:name="android.intent.action.REBOOT" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity>

frameworks/base/core/java/com/android/internal/app/ShutdownActivity.java

public class ShutdownActivity extends Activity {private static final String TAG = "ShutdownActivity";private boolean mReboot;private boolean mConfirm;private boolean mUserRequested;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Intent intent = getIntent();mReboot = Intent.ACTION_REBOOT.equals(intent.getAction());mConfirm = intent.getBooleanExtra(Intent.EXTRA_KEY_CONFIRM, false);mUserRequested = intent.getBooleanExtra(Intent.EXTRA_USER_REQUESTED_SHUTDOWN, false);final String reason = mUserRequested? PowerManager.SHUTDOWN_USER_REQUESTED: intent.getStringExtra(Intent.EXTRA_REASON);Slog.i(TAG, "onCreate(): confirm=" + mConfirm);Thread thr = new Thread("ShutdownActivity") {@Overridepublic void run() {IPowerManager pm = IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));try {if (mReboot) {pm.reboot(mConfirm, null, false);} else {pm.shutdown(mConfirm, reason, false);}} catch (RemoteException e) {}}};thr.start();finish();// Wait for us to tell the power manager to shutdown.try {thr.join();} catch (InterruptedException e) {}}
}

高温关机

<integer name="config_shutdownBatteryTemperature">680</integer>

超出这个定义的温度就关机,前文模拟器中获取的温度是 250 ,还是很安全的。

		private int mShutdownBatteryTemperature;//...public BatteryService(Context context) {// ...mShutdownBatteryTemperature = mContext.getResources().getInteger(com.android.internal.R.integer.config_shutdownBatteryTemperature);// ...}// ...shutdownIfOverTempLocked();// ...private void shutdownIfOverTempLocked() {// shut down gracefully if temperature is too high (> 68.0C by default)// wait until the system has booted before attempting to display the// shutdown dialog.if (mHealthInfo.batteryTemperature > mShutdownBatteryTemperature) {mHandler.post(new Runnable() {@Overridepublic void run() {if (mActivityManagerInternal.isSystemReady()) {Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);intent.putExtra(Intent.EXTRA_REASON,PowerManager.SHUTDOWN_BATTERY_THERMAL_STATE);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mContext.startActivityAsUser(intent, UserHandle.CURRENT);}}});}}

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

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

相关文章

从零起步:学习数据结构的完整路径

文章目录 1. 基础概念和前置知识2. 线性数据结构3. 栈和队列4. 树结构5. 图结构6. 散列表和哈希表7. 高级数据结构8. 复杂性分析和算法设计9. 实践和项目10. 继续学习和深入11. 学习资源12. 练习和实践 &#x1f389;欢迎来到数据结构学习专栏~从零起步&#xff1a;学习数据结构…

Java实现根据短连接获取1688商品详情数据,1688淘口令接口,1688API接口封装方法

要通过1688的API获取商品详情数据&#xff0c;您可以使用1688开放平台提供的接口来实现。以下是一种使用Java编程语言实现的示例&#xff0c;展示如何通过1688开放平台API获取商品详情属性数据接口&#xff1a; 首先&#xff0c;确保您已注册成为1688开放平台的开发者&#xf…

研华I/O板卡 Win10+Qt+Cmake 开发环境搭建

文章目录 一.研华I/O板卡 Win10QtCmake 开发环境搭建 一.研华I/O板卡 Win10QtCmake 开发环境搭建 参考这个链接安装研华I/O板卡驱动程序系统环境变量添加研华板卡dll Qt新建一个c项目 cmakeList.txt中添加研华库文件 cmake_minimum_required(VERSION 3.5)project(advantechDA…

设计模式(23种)简介

什么是设计模式&#xff1f; 设计模式&#xff08;Design pattern&#xff09;是解决特定问题的一系列套路&#xff0c;是前辈们的代码设计经验的总结。设计模式针对的是面向对象的语言。多态是设计模式的灵魂。 设计模式的优点&#xff1a; 可以提高程序员的思维能力、编程能…

【多线程】Thread类的用法

文章目录 1. Thread类的创建1.1 自己创建类继承Thread类1.2 实现Runnable接口1.3 使用匿名内部类创建Thread子类对象1.4 使用匿名内部类创建Runnable子类对象1.5 使用lambda创建 2. Thread常见的构造方法2.1 Thread()2.2 Thread(Runnable target)2.3 Thread(String name)2.4 Th…

软考高级系统架构设计师系列论文九十四:论计算机网络的安全性设计

软考高级系统架构设计师系列论文九十四:论计算机网络的安全性设计 一、计算机网络安全性设计相关知识点二、摘要三、正文四、总结一、计算机网络安全性设计相关知识点 软考高级系统架构设计师:计算机网络

全国三网话费充值优惠接口源码文档分享

话费充值接口文档 接口版本&#xff1a;1.0 ―、引言 文档概述 本文档提供话费充值接口规范说明&#xff0c;提供一整套的完整的接入示例(http 接口)供商户参 考&#xff0c;可以帮助商户开发人员快速完成接口开发与联调&#xff0c;实现与话费充值系统的交易互联。 公司官网…

Flink_state 的优化与 remote_state 的探索

摘要&#xff1a;本文整理自 bilibili 资深开发工程师张杨&#xff0c;在 Flink Forward Asia 2022 核心技术专场的分享。本篇内容主要分为四个部分&#xff1a; 相关背景state 压缩优化Remote state 探索未来规划 点击查看原文视频 & 演讲PPT 一、相关背景 1.1 业务概况 从…

【EI检索稳定】第六届电力电子与控制工程国际学术会议(ICPECE 2023)

第六届电力电子与控制工程国际学术会议 2023 6th International Conference on Power Electronics and Control Engineering (ICPECE 2023) 第六届电力电子与控制工程国际学术会议由广西大学主办&#xff0c;重庆大学、华东交通大学、长春理工大学、大连交通大学联合主办。电…

【AI模型】gym强化学习仿真平台配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍gym强化学习仿真平台配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&…

Linux内核学习(十)—— 块 I/O 层(基于Linux 2.6内核)

目录 一、剖析一个块设备 二、缓冲区和缓冲区头 三、bio 结构体 四、请求队列 五、I/O 调度程序 系统中能够随机&#xff08;不需要按顺序&#xff09;访问固定大小数据片&#xff08;chunks&#xff09;的硬件设备称作块设备&#xff0c;这些固定大小的数据片就称作块。最…

为什么会形成缓存雪崩?缓存雪崩解决方案

什么是缓存雪崩 缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库&#xff0c;瞬间耗尽数据库资源&#xff0c;导致数据库无法使用。 造成缓存雪崩问题的原因是是大量key拥有了相同的过期时间&#xff0c;比如对课程信息设置缓存过期时间为10分钟&#xff0…

回归预测 | MATLAB实现WOA-RBF鲸鱼优化算法优化径向基函数神经网络多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现WOA-RBF鲸鱼优化算法优化径向基函数神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现WOA-RBF鲸鱼优化算法优化径向基函数神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#…

大数据、AI和云原生:引领未来软件开发的技术演进

文章目录 **1. 数据驱动的创新&#xff1a;****2. 智能化应用的兴起&#xff1a;****3. 云原生的敏捷和可扩展性&#xff1a;****4. 实时性和即时性&#xff1a;****5. 数据隐私和安全&#xff1a;****6. 跨平台和跨设备&#xff1a;****7. 自动化和智能编程&#xff1a;****8.…

【Hello Algorithm】最大线段重合及加强堆

本篇博客简介&#xff1a;介绍加强堆 加强堆 最大线段重合问题加强堆 计算时间复杂度的技巧 一般来说 我们在刷算法的时候都要求C/C语言在1到2s之内完成 java这种语言在2到4秒之内完成 而与之对应的指令条数就是 十的八次方 左右 不会超过一个数量级 所以说根据上面的结论 我…

607. 销售员

import pandas as pddef sales_person(sales_person: pd.DataFrame, company: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:try:# 找到名为 "RED" 的公司的 com_idred_company_id company[company[name] RED][com_id].values[0]# 找到与名为 "RE…

Redis 高可用与集群

Redis 高可用与集群 虽然 Redis 可以实现单机的数据持久化&#xff0c;但无论是 RDB 也好或者 AOF 也好&#xff0c;都解决 不了单点宕机问题&#xff0c;即一旦单台 redis 服务器本身出现系统故障、硬件故障等问题后&#xff0c; 就会直接造成数据的丢失&#xff0c;因此需要…

Unity中的数学基础——贝塞尔曲线

一&#xff1a;前言 一条贝塞尔曲线是由一组定义的控制点P0到 Pn&#xff0c;n1为线性&#xff0c;n2为二次......第一个和最后一个控制点称为起点和终点&#xff0c;中间的控制点一般不会位于曲线上 获取两个点之间的点就是通过线性插值&#xff08; Mathf.Lerp&#xff09…

AR室内导航技术之技术说明与效果展示

随着科技的飞速发展&#xff0c;我们周围的环境正在经历着一场数字化的革命。其中&#xff0c;AR室内导航技术以其独特的魅力&#xff0c;为我们打开了一扇通往全新数字化世界的大门。本文将为您详细介绍这一技术的实现原理、工具应用以及成品展示&#xff0c;带您领略AR室内导…

k8s 安装 kubernetes安装教程 虚拟机安装k8s centos7安装k8s kuberadmin安装k8s k8s工具安装 k8s安装前配置参数

k8s采用master, node1, node2 。三台虚拟机安装的一主两从&#xff0c;机器已提前安装好docker。下面是机器配置&#xff0c;k8s安装过程&#xff0c;以及出现的问题与解决方法 虚拟机全部采用静态ip, master 30机器, node1 31机器, node2 32机器 机器ip 192.168.164.30 # ma…