Android system实战 — Android R(11) 进程保活白名单
Android system实战 — Android R 进程保活白名单
- 0. 前言
- 1. 具体实现
- 1.1 准备工作
- 1.2 源码实现
- 1.2.1 源码
- 1.2.2 diff文件
0. 前言
最近在Android R上实现一些需求,进行记录一下,关于进程保活的基础知识可以参考Android system — 进程生命周期与ADJ,实际上本质上,就是在提高进程的adj等级,从而达到保活的效果,当然如果你不care原理,也可以直接看下面具体实现。
1. 具体实现
主要涉及源码路径:
platform/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
1.1 准备工作
在源码实现之前,我们需要先准备进程白名单,并将其编译至system/etc/app_oom_adj.txt
白名单格式如下:
通用格式:
-序号(整数),包名
其中,序号值越小,则意味着对应的包名进程越受到保护,越难被系统回收内存;
该功能设置后,查看是否生效,可以通过查看进程的adj值来确认:
ps -A | grep “进程名”
cat /proc/进程名对应PID/oom_score_adj
例如:

1.2 源码实现
platform/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
1.2.1 源码
/** Copyright (C) 2019 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.android.server.am;import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION;
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
import static android.os.Process.SCHED_OTHER;
import static android.os.Process.THREAD_GROUP_BACKGROUND;
import static android.os.Process.THREAD_GROUP_DEFAULT;
import static android.os.Process.THREAD_GROUP_RESTRICTED;
import static android.os.Process.THREAD_GROUP_TOP_APP;
import static android.os.Process.THREAD_PRIORITY_DISPLAY;
import static android.os.Process.setProcessGroup;
import static android.os.Process.setThreadPriority;
import static android.os.Process.setThreadScheduler;import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
import static com.android.server.am.ActivityManagerService.DISPATCH_OOM_ADJ_OBSERVER_MSG;
import static com.android.server.am.ActivityManagerService.IDLE_UIDS_MSG;
import static com.android.server.am.ActivityManagerService.TAG_BACKUP;
import static com.android.server.am.ActivityManagerService.TAG_LRU;
import static com.android.server.am.ActivityManagerService.TAG_OOM_ADJ;
import static com.android.server.am.ActivityManagerService.TAG_PROCESS_OBSERVERS;
import static com.android.server.am.ActivityManagerService.TAG_PSS;
import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerService.TOP_APP_PRIORITY_BOOST;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;import android.app.ActivityManager;
import android.app.ApplicationExitInfo;
import android.app.usage.UsageEvents;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ServiceInfo;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.compat.IPlatformCompat;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.wm.ActivityServiceConnectionsHolder;
import com.android.server.wm.WindowProcessController;import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Vector;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;/*** All of the code required to compute proc states and oom_adj values.*/
public final class OomAdjuster {private static final String TAG = "OomAdjuster";static final String OOM_ADJ_REASON_METHOD = "updateOomAdj";static final String OOM_ADJ_REASON_NONE = OOM_ADJ_REASON_METHOD + "_meh";static final String OOM_ADJ_REASON_ACTIVITY = OOM_ADJ_REASON_METHOD + "_activityChange";static final String OOM_ADJ_REASON_FINISH_RECEIVER = OOM_ADJ_REASON_METHOD + "_finishReceiver";......Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}return true;});mTmpUidRecords = new ActiveUids(service, false);mTmpQueue = new ArrayDeque<ProcessRecord>(mConstants.CUR_MAX_CACHED_PROCESSES << 1);mNumSlots = ((ProcessList.CACHED_APP_MAX_ADJ - ProcessList.CACHED_APP_MIN_ADJ + 1) >> 1)/ ProcessList.CACHED_APP_IMPORTANCE_LEVELS;IBinder b = ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);mPlatformCompat = IPlatformCompat.Stub.asInterface(b);//for specific process priority guardparseCustomsizedAppOomAdj("/system/etc/app_oom_adj.txt");}void initSettings() {mCachedAppOptimizer.init();if (mService.mConstants.KEEP_WARMING_SERVICES.size() > 0) {final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);mService.mContext.registerReceiverForAllUsers(new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {synchronized (mService) {....../** Inform the oomadj observer of changes to oomadj. Used by tests. */@GuardedBy("mService")void reportOomAdjMessageLocked(String tag, String msg) {Slog.d(tag, msg);if (mService.mCurOomAdjObserver != null) {mService.mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();}}private class AppOomAdj {public int m_nOomAdj;public String m_sAppName;public AppOomAdj(int adj, String appname) {this.m_nOomAdj = adj;this.m_sAppName = appname;}}private Vector<AppOomAdj> mVec = null;private void parseCustomsizedAppOomAdj(String file) {try {FileReader fr = new FileReader(file);BufferedReader br=new BufferedReader(fr);String line = "";String[] arrs=null;AppOomAdj obj = null;if (mVec == null) {mVec = new Vector<AppOomAdj>();}while ((line=br.readLine()) != null) {arrs=line.split(",");obj = new AppOomAdj(Integer.parseInt(arrs[0]), arrs[1]);mVec.add(obj);}br.close();fr.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/** Applies the computed oomadj, procstate and sched group values and freezes them in set* */@GuardedBy("mService")private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,long nowElapsed) {boolean success = true;if (app.getCurRawAdj() != app.setRawAdj) {app.setRawAdj = app.getCurRawAdj();}int changes = 0;//Slog.d(TAG, "applyOomAdjLocked pkg: " + app.processName+",pid:"+ app.pid+",uid:"+ app.uid +",curAdj:"+app.curAdj+",setAdj:"+app.setAdj);if (mVec != null) {int i = 0;int oom_score_adj = 0;for (;i < mVec.size(); i++) {if (app.processName.equals(mVec.get(i).m_sAppName)) {//new curAdj point to {oom_score_adj}oom_score_adj = mVec.get(i).m_nOomAdj;app.curAdj = oom_score_adj;//Slog.d(TAG, "applyOomAdjLocked pkg:"+app.processName+" mVec app.curAdj:"+app.curAdj);}}}// don't compact during bootupif (mCachedAppOptimizer.useCompaction() && mService.mBooted) {// Cached and prev/home compactionif (app.curAdj != app.setAdj) {// Perform a minor compaction when a perceptible app becomes the prev/home app// Perform a major compaction when any app enters cached// reminder: here, setAdj is previous state, curAdj is upcoming stateif (app.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ &&(app.curAdj == ProcessList.PREVIOUS_APP_ADJ ||......}
1.2.2 diff文件
From 4a534042738f6793827ab51089bbdd0977b489ad Mon Sep 17 00:00:00 2001
From: yuefu.zhou <yuefu.zhou@amlogic.com>
Date: Fri, 03 Feb 2023 18:32:13 +0800
Subject: [PATCH] AMS: Support for configuring process priority. [2/2]PD#IPTV-19626Problem:
need support configure the process priority.Solution:
Support for configuring process priority.Verify:
S928XChange-Id: If5f82e86f2a33a8cfbdf664d6079a9ad904fc4ac
Signed-off-by: yuefu.zhou <yuefu.zhou@amlogic.com>
---diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index faa7dce..2d0ce94 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -110,6 +110,12 @@import java.util.ArrayDeque;import java.util.ArrayList;import java.util.Arrays;
+import java.util.Vector;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;/*** All of the code required to compute proc states and oom_adj values.
@@ -265,6 +271,9 @@/ ProcessList.CACHED_APP_IMPORTANCE_LEVELS;IBinder b = ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);mPlatformCompat = IPlatformCompat.Stub.asInterface(b);
+
+ //for specific process priority guard
+ parseCustomsizedAppOomAdj("/system/etc/app_oom_adj.txt");}void initSettings() {
@@ -2144,6 +2153,43 @@}}+ private class AppOomAdj {
+ public int m_nOomAdj;
+ public String m_sAppName;
+ public AppOomAdj(int adj, String appname) {
+ this.m_nOomAdj = adj;
+ this.m_sAppName = appname;
+ }
+ }
+
+ private Vector<AppOomAdj> mVec = null;
+ private void parseCustomsizedAppOomAdj(String file) {
+ try {
+ FileReader fr = new FileReader(file);
+ BufferedReader br=new BufferedReader(fr);
+ String line = "";
+ String[] arrs=null;
+ AppOomAdj obj = null;
+
+ if (mVec == null) {
+ mVec = new Vector<AppOomAdj>();
+ }
+
+ while ((line=br.readLine()) != null) {
+ arrs=line.split(",");
+ obj = new AppOomAdj(Integer.parseInt(arrs[0]), arrs[1]);
+ mVec.add(obj);
+ }
+
+ br.close();
+ fr.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+/** Applies the computed oomadj, procstate and sched group values and freezes them in set* */@GuardedBy("mService")private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
@@ -2155,6 +2201,19 @@}int changes = 0;
+ //Slog.d(TAG, "applyOomAdjLocked pkg: " + app.processName+",pid:"+ app.pid+",uid:"+ app.uid +",curAdj:"+app.curAdj+",setAdj:"+app.setAdj);
+ if (mVec != null) {
+ int i = 0;
+ int oom_score_adj = 0;
+ for (;i < mVec.size(); i++) {
+ if (app.processName.equals(mVec.get(i).m_sAppName)) {
+ //new curAdj point to {oom_score_adj}
+ oom_score_adj = mVec.get(i).m_nOomAdj;
+ app.curAdj = oom_score_adj;
+ //Slog.d(TAG, "applyOomAdjLocked pkg:"+app.processName+" mVec app.curAdj:"+app.curAdj);
+ }
+ }
+ }// don't compact during bootupif (mCachedAppOptimizer.useCompaction() && mService.mBooted) {相关文章:
Android system实战 — Android R(11) 进程保活白名单
Android system实战 — Android R 进程保活白名单0. 前言1. 具体实现1.1 准备工作1.2 源码实现1.2.1 源码1.2.2 diff文件0. 前言 最近在Android R上实现一些需求,进行记录一下,关于进程保活的基础知识可以参考Android system — 进程生命周期与ADJ&#…...
oracle表 分组,并查每组第一条
oracle主要用到的函数:OVER(PARTITION BY) mysql主要用到的函数:LIMIT (用到3个地方:分组列、组内排序列、表名) oracle: select t.* from ( select a.*, ROW_NUMBER() OVER (PARTITION BY 分组列 ORDER BY 组内排…...
Java代码弱点与修复之——DE: Dropped or ignored exception(无视或忽略异常)
弱点描述 Dropped or ignored exception(DE)指的是在代码中抛出的异常被捕获后被无视或忽略了,而不是被适当地处理。这种情况通常发生在程序员没有处理异常或处理异常时不小心忽略了异常的情况下。 Dropped or ignored exception会导致程序无法正常工作,因为异常会阻塞程…...
JavaEE简单示例——动态SQL之更新操作<set>元素
简单介绍: 在之前我们做的学生管理系统的时候,曾经有一个环节是修改学生的数据。我们在修改的时候是必须将student对象的三个属性全部填入信息,然后全部修改才可以,这样会造成一个问题就是在我们明明只需要修改一个属性的时候却要…...
【极海APM32替代笔记】低功耗模式配置及配置汇总
【极海APM32替代笔记】低功耗模式配置及配置汇总 文章总结:(后续更新以相关文章为准) 【STM32笔记】低功耗模式、WFI命令等进入不了休眠的可能原因(系统定时器SysTick一直产生中断) 【STM32笔记】HAL库低功耗模式配置…...
攻击者失手,自己杀死了僵尸网络 KmsdBot
此前,Akamai 的安全研究员披露了 KmsdBot 僵尸网络,该僵尸网络主要通过 SSH 爆破与弱口令进行传播。在对该僵尸网络的持续跟踪中,研究人员发现了一些有趣的事情。 C&C 控制 对恶意活动来说,最致命的就是夺取对 C&C 服务…...
东阿县高新技术企业认定条件和优惠政策 山东同邦科技分享
东阿县高新技术企业认定条件和优惠政策 山东同邦科技分享 高新技术企业 在《国家重点支持的高新技术领域》内,持续进行研究开发与技术成果转化,形成企业核心自主知识产权,并以此为基础开展经营活动,在中国境内(不包…...
【基础算法】哈希表(拉链法)
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
硬件学习 软件Cadence day07 PCB 底板电路图布线
1.根据原理图的元器件, 选择在 PCB 芯片制作的元器件 (allegro中原理图和pcb中元件的交互) 1.首先完成下列操作 可以尝试先关闭再打开, 等下操作的时候就好 发现新增的发光物体!! 2.完成操作 ,…...
SkyWalking仪表盘使用
Skywalking仪表盘使用 1 仪表盘 作用:查看被监控服务的运行状态。 1)监控面板 1.1 APM APM:应用性能管理,通过各种探针采集数据,收集关键指标,同时搭配数据呈现以实现对应用程序性能管理和故障管理的系统化解决方案…...
面渣逆袭:分布式十二问,万字图文详解
大家好,我是老三,不管今年金三银四如何,面渣逆袭系列继续,这期我们来看看分布式。 分布式理论 1. 说说CAP原则? CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性…...
设计模式C++实现23:中介者模式(Mediator)
部分内容参考大话设计模式第25章;本实验通过C语言实现。 一 原理 意图:用一个中介对象来封装一系列对象的交互,中介者使得各个对象不需要显示地相互引用,从而使耦合松散,而且可以独立地改变它们之间的交互。 上下文…...
Java方法【未完待续】
目录 前言 一、什么是方法? 二、方法的定义和调用 方法的定义 方法的调用 三、方法的重载 重载规则 实现理论 总结 前言 随着对Java这一编程语言的深入学习,大家可能会遇到一个熟悉又陌生的词——方法,其实Java方法就是我们学习C/C时…...
(考研湖科大教书匠计算机网络)第六章应用层-第一、二节:应用层概述和C/S及P2P
获取pdf:密码7281专栏目录首页:【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一:应用层概述二:客户/服务器(C/S)和对等(P2P)方式(1)客户/服务器&…...
禅道bug提醒脚本部署
环境准备 nginxpython3 服务器目录 以下目录为自定义配置,需在 nginx 默认配置文件的http{}内添加 include /www/conf/*.conf; 才会生效 /www ├── conf "存放配置文件 │ └── lowCode.zyl.conf "低代码bug统计页配置 ├── wwwlogs "存…...
利用spring的retry重试编写Feign远程调用重试
自定义注解FeignRetry为了解决上面提到的问题,让Feign调用的每个接口单独配置不同的重试机制。我们使用了面向切面编程并编写了一个自定义注解:FeignRetry。此注释的工作方式类似于Retryable的包装器,并与其共享相同的规范以避免混淆。Target…...
Docker启动RabbitMQ,实现生产者与消费者
目录 一、Docker拉取镜像并启动RabbitMQ 二、Hello World (一)依赖导入 (二)消息生产者 (三)消息消费者 三、实现轮训分发消息 (一)抽取工具类 (二)启…...
【C语言】函数栈帧的创建与销毁
Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 0.ebp和esp是如何来维护栈帧的呢? 1.为什么局部变量的值不初始化是随机的? 2.局部变量是怎么创建的? 3 .函数是如何传参的?传参的顺序是怎样的 4.函数是如何调用的 …...
【Git】使用Git上传项目到远程仓库Gitee码云步骤详解
电脑里存放了很多项目,有的备份,有的没备份,如果不仔细分类管理的话,时间一长,到时看到那就会觉得非常杂乱,很难整理,这里有一个叫源代码托管,用过它的都知道,方便管理和…...
Head First设计模式---3.装饰者模式
3.1装饰者模式 亦称: 装饰者模式、装饰器模式、Wrapper、Decorator 装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 举个例子:天气很冷,我们一件一件穿衣服,…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
