MTK 关机充电时充电IC正常,电池正常充电,但是充电动画一直显示0%

平台

mt8168+mt6357+chargerIC

问题

MTK 关机充电时充电IC正常,电池正常充电,但是充电动画一直显示0%

相关说明

只截取部分记录一下思路
on charger 触发
工程中的一些on charger配置用于开机时(bootmode is charger)充电触发。
如:device\mediatek\mt8168\init.mt8168.rc

on chargerwait /sys/bus/platform/devices/mt6357-charger-type-detection 10symlink /dev/block/platform/soc/11230000.mmc /dev/block/platform/bootdevice# mount ext4 /dev/block/platform/bootdevice/by-name/system /system ro wait# Permissions for System Server and daemons.chown system system /sys/power/autosleepchown system system /sys/power/statechown system system /sys/power/wakeup_countchown radio wakelock /sys/power/wake_lockchown radio wakelock /sys/power/wake_unlockchmod 0660 /sys/power/statechmod 0660 /sys/power/wake_lockchmod 0660 /sys/power/wake_unlockchmod 0660 /sys/power/wakeup_countstart kpoc_chargerchmod 0666 /dev/kmsgchmod 0775 /mnt/vendormkdir /mnt/vendor/nvcfgmount ext4 /dev/block/platform/bootdevice/by-name/nvcfg /mnt/vendor/nvcfg rw waitchown system system /mnt/vendor/nvcfgchmod 0771 /mnt/vendor/nvcfgrestorecon_recursive /mnt/vendor/nvcfgwrite /sys/devices/platform/battery_meter/FG_daemon_log_level 7write /sys/bus/platform/devices/battery/FG_daemon_log_level 7start fuelgaugedstart fuelgauged_nvramchown system system /sys/class/leds/lcd-backlight/brightnesschown system system /sys/class/leds/red/brightnesschown system system /sys/class/leds/green/brightness#    start vendor.light-default# disable USBwrite /sys/devices/platform/mt_usb/cmode 0

hardware\interfaces\health\2.1\default\android.hardware.health@2.1-service.rc

service health-hal-2-1 /vendor/bin/hw/android.hardware.health@2.1-serviceclass hal chargeruser systemgroup systemcapabilities WAKE_ALARM BLOCK_SUSPENDfile /dev/kmsg w

vendor\mediatek\proprietary\external\charger 关机充电时调用的服务。
kpoc_charger.rc内容:

on chargerstart kpoc_chargerservice kpoc_charger /system/bin/kpoc_chargerclass chargergroup system wakelockcapabilities BLOCK_SUSPEND SYS_ADMIN SYS_BOOT

启动流程(\system\core\init\init.cpp)中判断是否充电模式开机判断如下:

int SecondStageMain(int argc, char** argv) {。。。// Don't mount filesystems or start core system services in charger mode.std::string bootmode = GetProperty("ro.bootmode", "");LOG(INFO) << "init : xmhxj debug : bootmode is " << bootmode;if (bootmode == "charger") {am.QueueEventTrigger("charger");} else {am.QueueEventTrigger("late-init");}
。。。
}

hardware\interfaces\health 提供vendor和system的接口调用。
如电量获取getCapacity:
hardware\interfaces\health\2.0\default\Health.cpp

Return<void> Health::getCapacity(getCapacity_cb _hidl_cb) {getProperty<int32_t>(battery_monitor_, BATTERY_PROP_CAPACITY, 0, _hidl_cb);return Void();
}

关联调用的是:
system\core\healthd\BatteryMonitor.cpp

status_t BatteryMonitor::getProperty(int id, struct BatteryProperty *val) {status_t ret = BAD_VALUE;std::string buf;val->valueInt64 = LONG_MIN;switch(id) {。。。case BATTERY_PROP_CAPACITY:if (!mHealthdConfig->batteryCapacityPath.isEmpty()) {val->valueInt64 =getIntField(mHealthdConfig->batteryCapacityPath);ret = OK;} else {ret = NAME_NOT_FOUND;}break;
。。。return ret;
}

healthd服务相关(system\core\healthd ),用于关机充电时获取电池信息的地方。
void BatteryMonitor::updateValues函数,更新底层上报的电池信息

void BatteryMonitor::updateValues(void) {initHealthInfo(mHealthInfo.get());HealthInfo_1_0& props = mHealthInfo->legacy.legacy;KLOG_WARNING(LOG_TAG, "BM xmhxj debug :mHealthdConfig->batteryPresentPath.isEmpty() %d\n", mHealthdConfig->batteryPresentPath.isEmpty());KLOG_WARNING(LOG_TAG, "BM xmhxj debug :mHealthdConfig->batteryPresentPath %s\n",mHealthdConfig->batteryPresentPath.string());if (!mHealthdConfig->batteryPresentPath.isEmpty()){KLOG_WARNING(LOG_TAG, "BM xmhxj debug :!mHealthdConfig->batteryPresentPath.isEmpty() %s\n", mHealthdConfig->batteryPresentPath.string());props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);} else {props.batteryPresent = mBatteryDevicePresent;KLOG_WARNING(LOG_TAG, "BM xmhxj debug : mHealthdConfig->batteryPresentPath.isEmpty() mBatteryDevicePresent %d\n", mBatteryDevicePresent);}KLOG_WARNING(LOG_TAG, "BM xmhxj debug : props.batteryPresent %d\n", props.batteryPresent);props.batteryLevel = mBatteryFixedCapacity ?mBatteryFixedCapacity :getIntField(mHealthdConfig->batteryCapacityPath);props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;if (!mHealthdConfig->batteryCurrentNowPath.isEmpty())props.batteryCurrent = getIntField(mHealthdConfig->batteryCurrentNowPath);if (!mHealthdConfig->batteryFullChargePath.isEmpty())props.batteryFullCharge = getIntField(mHealthdConfig->batteryFullChargePath);if (!mHealthdConfig->batteryCycleCountPath.isEmpty())props.batteryCycleCount = getIntField(mHealthdConfig->batteryCycleCountPath);if (!mHealthdConfig->batteryChargeCounterPath.isEmpty())props.batteryChargeCounter = getIntField(mHealthdConfig->batteryChargeCounterPath);if (!mHealthdConfig->batteryCurrentAvgPath.isEmpty())mHealthInfo->legacy.batteryCurrentAverage =getIntField(mHealthdConfig->batteryCurrentAvgPath);if (!mHealthdConfig->batteryChargeTimeToFullNowPath.isEmpty())mHealthInfo->batteryChargeTimeToFullNowSeconds =getIntField(mHealthdConfig->batteryChargeTimeToFullNowPath);if (!mHealthdConfig->batteryFullChargeDesignCapacityUahPath.isEmpty())mHealthInfo->batteryFullChargeDesignCapacityUah =getIntField(mHealthdConfig->batteryFullChargeDesignCapacityUahPath);props.batteryTemperature = mBatteryFixedTemperature ?mBatteryFixedTemperature :getIntField(mHealthdConfig->batteryTemperaturePath);std::string buf;if (readFromFile(mHealthdConfig->batteryCapacityLevelPath, &buf) > 0)mHealthInfo->batteryCapacityLevel = getBatteryCapacityLevel(buf.c_str());if (readFromFile(mHealthdConfig->batteryStatusPath, &buf) > 0)props.batteryStatus = getBatteryStatus(buf.c_str());if (readFromFile(mHealthdConfig->batteryHealthPath, &buf) > 0)props.batteryHealth = getBatteryHealth(buf.c_str());if (readFromFile(mHealthdConfig->batteryTechnologyPath, &buf) > 0)props.batteryTechnology = String8(buf.c_str());double MaxPower = 0;for (size_t i = 0; i < mChargerNames.size(); i++) {String8 path;path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,mChargerNames[i].string());if (getIntField(path)) {path.clear();path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,mChargerNames[i].string());switch(readPowerSupplyType(path)) {case ANDROID_POWER_SUPPLY_TYPE_AC:props.chargerAcOnline = true;break;case ANDROID_POWER_SUPPLY_TYPE_USB:props.chargerUsbOnline = true;break;case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:props.chargerWirelessOnline = true;break;default:KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",mChargerNames[i].string());}path.clear();path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,mChargerNames[i].string());int ChargingCurrent =(access(path.string(), R_OK) == 0) ? getIntField(path) : 0;path.clear();path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,mChargerNames[i].string());int ChargingVoltage =(access(path.string(), R_OK) == 0) ? getIntField(path) :DEFAULT_VBUS_VOLTAGE;double power = ((double)ChargingCurrent / MILLION) *((double)ChargingVoltage / MILLION);if (MaxPower < power) {props.maxChargingCurrent = ChargingCurrent;props.maxChargingVoltage = ChargingVoltage;MaxPower = power;}}}
}

服务初始化函数void BatteryMonitor::init函数:

void BatteryMonitor::init(struct healthd_config *hc) {  String8 path;  char pval[PROPERTY_VALUE_MAX];
...  mHealthdConfig = hc;  std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);  if (dir == NULL) {  KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);  } else {  struct dirent* entry;  while ((entry = readdir(dir.get()))) {  const char* name = entry->d_name;  std::vector<String8>::iterator itIgnoreName;  KLOG_WARNING(LOG_TAG, "BM xmhxj debug :INIT 111 name %s\n",name);  if (!strcmp(name, ".") || !strcmp(name, ".."))  continue;  itIgnoreName = find(hc->ignorePowerSupplyNames.begin(),  hc->ignorePowerSupplyNames.end(), String8(name));  if (itIgnoreName != hc->ignorePowerSupplyNames.end())  continue;  KLOG_WARNING(LOG_TAG, "BM xmhxj debug :INIT 222 name %s\n",name);  // Look for "type" file in each subdirectory  path.clear();  path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);  KLOG_WARNING(LOG_TAG, "BM xmhxj debug :INIT 333 readPowerSupplyType %d\n",readPowerSupplyType(path));  switch(readPowerSupplyType(path)) {  ...  case ANDROID_POWER_SUPPLY_TYPE_BATTERY:  KLOG_WARNING(LOG_TAG, "BM xmhxj debug :INIT 333 name %s\n",name);  // Some devices expose the battery status of sub-component like  // stylus. Such a device-scoped battery info needs to be skipped  // in BatteryMonitor, which is intended to report the status of  // the battery supplying the power to the whole system.  if (isScopedPowerSupply(name)) continue;  mBatteryDevicePresent = true;  KLOG_WARNING(LOG_TAG, "BM xmhxj debug :INIT 444 name %s\n",name);  if (mHealthdConfig->batteryStatusPath.isEmpty()) {  path.clear();  path.appendFormat("%s/%s/status", POWER_SUPPLY_SYSFS_PATH,  name);  if (access(path, R_OK) == 0)  mHealthdConfig->batteryStatusPath = path;  }  if (mHealthdConfig->batteryHealthPath.isEmpty()) {  path.clear();  path.appendFormat("%s/%s/health", POWER_SUPPLY_SYSFS_PATH,  name);  if (access(path, R_OK) == 0)  mHealthdConfig->batteryHealthPath = path;  }  KLOG_WARNING(LOG_TAG, "BM xmhxj debug :mHealthdConfig->batteryPresentPath %s\n",mHealthdConfig->batteryPresentPath.string());  if (mHealthdConfig->batteryPresentPath.isEmpty()) {  path.clear();  path.appendFormat("%s/%s/present", POWER_SUPPLY_SYSFS_PATH,  name);  if (access(path, R_OK) == 0){  mHealthdConfig->batteryPresentPath = path;  KLOG_WARNING(LOG_TAG, "BM xmhxj debug : %s/%s/present ok\n",POWER_SUPPLY_SYSFS_PATH,name);  } else {  KLOG_WARNING(LOG_TAG, "BM xmhxj debug : %s/%s/present fail \n",POWER_SUPPLY_SYSFS_PATH,name);  }  }  KLOG_WARNING(LOG_TAG, "BM xmhxj debug :init batteryPresentPath : %s \n",mHealthdConfig->batteryPresentPath.c_str());  ...  // Typically the case for devices which do not have a battery and  // and are always plugged into AC mains.  if (!mBatteryDevicePresent) {  KLOG_WARNING(LOG_TAG, "No battery devices found\n");  hc->periodic_chores_interval_fast = -1;  hc->periodic_chores_interval_slow = -1;  } else {
...
}

vendor\mediatek\proprietary\external\libshowlogo 充电图片显示服务代码
最终调用void show_battery_capacity(unsigned int capacity)函数为电量显示时调用。

现象

log分析

抓取的异常串口log分析:

[    4.746224][  T165] init: BOOTPROF:      4746.206241:INIT:init  [    4.803653][    T1] init: init 6: [4801][0]processing action (charger) from (/system/etc/init/hw/init.rc:1093)
[    4.805786][    T1] init: init 21: [4801][0]starting service 'kpoc_charger'...  [    4.816035][    T1] init: init 21: [4801][0]starting service 'health-hal-2-1'...  [    4.817246][    T1] init: init 21: [4801][0]Opened file '/dev/kmsg', flags 1  [    4.829566][    T1] init: init 21: [4828][0]processing action (charger) from (/vendor/etc/init/hw/init.mt8168.rc:71)
[    4.895068][    T1] init: init 21: [4892][0]Command 'write /sys/bus/platform/devices/battery/FG_daemon_log_level 7' action=charger (/vendor/etc/init/hw/init.mt8168.rc:96) took 1ms and failed: Unable to write to file '/sys/bus/platform/devices/battery/FG_daemon_log_level': open() failed: Permission denied
[    4.900952][    T1] init: init 21: [4900][0]processing action (charger) from (/vendor/etc/init/hw/init.mt8168.usb.rc:73)
[    4.925939][  T206] android.hardwar: healthd: BM xmhxj debug :INIT 111 name .
[    4.926948][  T206] android.hardwar: healthd: BM xmhxj debug :INIT 111 name ..
[    4.927952][  T206] android.hardwar: healthd: No battery devices found
[    4.932247][    T1] init: init 21: [4931][0]processing action (charger) from (/vendor/etc/init/hw/init.project.rc:58)
[    4.935972][    T1] init: init 21: [4934][0]starting service 'fuelgauged'...
[    4.937344][  T206] health@2.1-serv: healthd: BM xmhxj debug :mHealthdConfig->batteryPresentPath.isEmpty() 1
[    4.938631][  T206] health@2.1-serv: healthd: BM xmhxj debug :mHealthdConfig->batteryPresentPath
[    4.939981][  T163] init: init 23: [4939][8]ReapLogT PropSet [sys.usb.configfs]=[0]4738 [sys.lmk.reportkills]=[1]4740 [init.svc.kpoc_charger]=[running]4812 [ro.boottime.kpoc_charger]=[4808788307]4813 [init.svc_debug_pid.kpoc_charger]=[204]4813 [init.svc.health-hal-2-1]=[running]4826 [ro.boottime.health-hal-2-1]=[4824270692]4827 [init.svc_debug_pid.health-hal-2-1]=[206]4828 [hwservicemanager.ready]=[true]4912 [sys.usb.configfs]=[1]4923 [sys.usb.controller]=[11201000.usb]4924 [vendor.usb.acm_cnt]=[0]4926 [vendor.usb.acm_port0]=[]4927 [vendor.usb.acm_port1]=[]4928 [vendor.usb.acm_enable]=[0]4928 [vendor.usb.clear]=[boot]4929 [sys.usb.config]=[hid]4930 Done
[    4.944828][  T206] health@2.1-serv: healthd: BM xmhxj debug : mHealthdConfig->batteryPresentPath.isEmpty() mBatteryDevicePresent 0
[    4.948799][  T206] health@2.1-serv: healthd: BM xmhxj debug : props.batteryPresent 0
[    4.949877][  T206] health@2.1-serv: healthd: xmhxj debug : battery none chg=
[    4.950707][    T1] init: init 6: [4948][0]starting service 'fuelgauged_nvram'...
[    4.950816][  T206] health@2.1-serv: healthd: BM xmhxj debug :mHealthdConfig->batteryPresentPath.isEmpty() 1

从log中可以知道初始化时获取power_supply节点下的信息为空

[    4.925939][  T206] android.hardwar: healthd: BM xmhxj debug :INIT 111 name .
[    4.926948][  T206] android.hardwar: healthd: BM xmhxj debug :INIT 111 name ..
[    4.927952][  T206] android.hardwar: healthd: No battery devices found
[    4.937344][  T206] health@2.1-serv: healthd: BM xmhxj debug :mHealthdConfig->batteryPresentPath.isEmpty() 1

导致

health@2.1-serv: healthd: xmhxj debug : battery none chg=

使得关机充电时充电信息的获取无法从healthd中得到。使得加载为0%

而比较正常的开机log为:

[   12.834990][    T1] init: init 23: [12681][0]starting service 'health-hal-2-1'...
...
[   13.094853][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 111 name .
[   13.095843][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 111 name ..
[   13.096817][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 111 name mtk-gauge
[   13.123017][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 222 name mtk-gauge
[   13.124642][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 333 readPowerSupplyType 0
[   13.145360][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 111 name battery
[   13.146437][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 222 name battery
[   13.170693][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 333 readPowerSupplyType 4
[   13.172061][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 333 name battery
[   13.205482][  T426] android.hardwar: healthd: BM xmhxj debug :INIT 444 name battery

对策

在void BatteryMonitor::init(struct healthd_config hc)初始化函数中添加延迟
具体修改如下:

void BatteryMonitor::init(struct healthd_config *hc) {  String8 path;  char pval[PROPERTY_VALUE_MAX];
+
+    nsecs_t now;
+    nsecs_t start_t;
+    now = nanoseconds_to_seconds(systemTime());
+    KLOG_WARNING(LOG_TAG, " BM xmhxj debug :now  %ld\n", (long)now);
+  //获取系统时间,开机时间运行小于15s不断循环
+    while((nanoseconds_to_seconds(systemTime()) <= 15 ));
+    start_t = nanoseconds_to_seconds(systemTime());
+    KLOG_WARNING(LOG_TAG, " BM xmhxj debug : start_t  %ld\n", (long)start_t);
+    KLOG_WARNING(LOG_TAG, " BM xmhxj debug : 222 now  %ld\n", (long)(start_t - now));      mHealthdConfig = hc;  std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(POWER_SUPPLY_SYSFS_PATH), closedir);  if (dir == NULL) {
...
}

截取log如下:

    Line 2872: [    5.034645][  T195] android.hardwar: healthd:  BM xmhxj debug :now  5Line 5280: [   16.001043][  T195] android.hardwar: healthd:  BM xmhxj debug : start_t  16Line 5281: [   16.001955][  T195] android.hardwar: healthd:  BM xmhxj debug : 222 now  11Line 5282: [   16.003457][  T195] android.hardwar: healthd: BM xmhxj debug :INIT 111 name .Line 5283: [   16.004371][  T195] android.hardwar: healthd: BM xmhxj debug :INIT 111 name ..Line 5284: [   16.005314][  T195] android.hardwar: healthd: BM xmhxj debug :INIT 111 name mtk-gaugeLine 5285: [   16.006321][  T195] android.hardwar: healthd: BM xmhxj debug :INIT 222 name mtk-gaugeLine 5286: [   16.007688][  T195] android.hardwar: healthd: BM xmhxj debug :INIT 333 readPowerSupplyType 0Line 5287: [   16.008824][  T195] android.hardwar: healthd: BM xmhxj debug :INIT 111 name batteryLine 5288: [   16.009910][  T195] android.hardwar: healthd: BM xmhxj debug :INIT 222 name batteryLine 5289: [   16.011025][  T195] android.hardwar: healthd: BM xmhxj debug :INIT 333 readPowerSupplyType 4

总结

由于项目创建时的一些客制化修改导致关机充电服务过早的被调用,而底层kernel中的power_supply相关的节点设备(battery)等还未初始化注册,使得上层的初始化时读取的power_supply下的节点为空导致。解决方式为:在上层的初始化中添加延迟等待,模拟到正常开机时调用的时刻再执行节点设备获取。

本人有道笔记记录同步:
1:http://note.youdao.com/noteshare?id=418b40be3ff208d70cc80b9ff3f21b55&sub=8751EEB0DD0E47A28ADD474328B26DC6

MTK 关机充电时充电IC正常,电池正常充电,但是充电动画一直显示0%相关推荐

  1. 苹果充电时一充一停怎么办_苹果充电线一会儿能充一会儿不能充怎么回事

    很多小伙伴都会因为iPhone手机充不进去电而烦恼,这里讲下解决办法:1.电源和充电器问题2.iPhone尾插有水渍.异物或损坏3.充电环境的气温过低4.电池损耗过度或者电池管理IC损坏5.手机系统故 ...

  2. android充电状态广播,教学--监测电池的电量与充电状态

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 当你想通过改变后台更新操作的频率来减少对电池寿命的影响,那么首先需要检查当前电量与充电状态. 电池的电量与是否在充电状态会影响到一个程序去执行更新的操作. ...

  3. android监测电池的电量与充电状态

    转 原文:http://developer.android.com/training/monitoring-device-state/battery-monitoring.html http://hu ...

  4. 充电枪cp信号控制板_一种车载充电机检测CP信号的抗干扰处理方法与流程

    本发明涉及电动汽车充电技术领域,尤其涉及一种车载充电机检测CP信号的抗干扰处理方法. 背景技术: 能源和环保的双重压力使得新能源车越来越成为未来的汽车主流,目前的新能源车主要以电动车为主,这其中又包括 ...

  5. SH7001单电池恒压线性充电IC

    SH7001单电池恒压线性充电IC 简介 泛海微SH7001 是一款完整的单节锂离子电池采用 恒定电流/ 恒定电压线性充电器.其 SOT 封装与较 少的外部元件数目使得 SH7001成为便携式应用 的 ...

  6. 苹果x充电慢是什么原因_手机资讯:为什么 iPhone 充电从 99% 到 100% 时特别慢是电池故障吗...

    如今使用IT数码设备的小伙伴们是越来越多了,那么IT数码设备当中是有很多知识的,这些知识很多小伙伴一般都是不知道的,就好比最近就有很多小伙伴们想要知道为什么 iPhone 充电从 99% 到 100% ...

  7. Macbook充电和电池保养 rmbp充电时插电源吗?

    今早和朋友谈到Macbook (我俩都是rMBP 15")充电的问题,他提到看过苹果官方视频,其中提到Macbook充电1000个循环的问题.所以他平时都是插着电源用电脑,就怕循环一次少一次 ...

  8. 3合1集成充电宝移动电源IC

    3合1移动电源IC 同步整流3合1移动电源IC: 型号 功能 包含的模块 工作模式 最低 放电 电压 充电 电流 升压 效率 待机 功耗 保护功能 封装 HM5920 0.8A线性充电 1A同步升压放 ...

  9. 浅析手机充电时不断重启

    我这里说的不断重启与主板问题的无限重启不是一个概念! 手机不断重启,以前只是听说,现在遇见过两回.姑且叫不断重启吧,因为我实在是没有耐心让继续下去,就果断地处理了. 我手机两次不断重启,都是在手机电池 ...

最新文章

  1. Angular--TypeScript finalize 方法
  2. Android BLE学习(二): Android与51822蓝牙模块通信流程的实现与分析
  3. 在C++中子类继承和调用父类的构造函数方法
  4. WebServices 基础知识
  5. 听云支持.NET Core的应用性能监控
  6. C语言中printf(built: %s %s,__TIME__,__DATE__);方便调试
  7. Nginx负载调度器+双Tomcat负载及会话共享+MySQL后端数据库
  8. B+/-Tree原理(mysql索引数据结构)
  9. 【C++/Python 双语言实现】Luogu1196 银河英雄传说 + Python函数的定义与调用
  10. ArcGIS中的北京54和西安80投影坐标系详解
  11. 152、全面图解交换机接口及连接
  12. Pycharm中不显示latest version
  13. 小米手机第三方卡刷软件_小米Max卡刷教程_小米Max用recovery刷第三方系统包
  14. java 文件移动_java 文件移动
  15. Admin-UI分布式微服务监控中心
  16. c语言中数组arr的表示含义
  17. java接口 运动员,JAVA面向对象进阶实例【教练和运动员日常安排】
  18. 多行文本超过一定行数后显示展开功能
  19. 计算机平面设计会学cad吗,请问学建筑与室内设计哪样好是不是都要学CAD
  20. 遍历和添加json对象的属性 和 遍历普通js对象的属性

热门文章

  1. File.listFiles()返回null
  2. Onvif的PTZ控制
  3. Automatically Labeled Data Generation for Large Scale Event Extraction
  4. Python 搜索、排序、复杂度分析
  5. 深入浅出的数据分析方法
  6. 安居客住房系统-基于Python-Django前后端分离开发(一)——初始化项目及ORM关系映射
  7. unity2D横版游戏教程-2 代码实现
  8. springbootJpa 连接南大通用数据库Gbase配置
  9. 常用默认端口+URL解析+HTTP详解
  10. 青海大学计算机专业在全国排名,青海大学优势专业排名,2021年青海大学最好的专业排名...