")]),t._v(" to packages fold。 使用上,使用 "),e("code",[t._v("command+shfit+p")]),t._v(", 键入 'Toggle Hexer View'")]),t._v(" "),e("h3",{attrs:{id:"other"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#other"}},[t._v("#")]),t._v(" other")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://packagecontrol.io/packages/Compare%20Side-By-Side",target:"_blank",rel:"noopener noreferrer"}},[t._v("Compare Side-By-Side"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/dzhibas/SublimePrettyJson",target:"_blank",rel:"noopener noreferrer"}},[t._v("SublimePrettyJson"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=l.exports}}]);
\ No newline at end of file
diff --git a/assets/js/135.cb7a50a2.js b/assets/js/135.cb7a50a2.js
new file mode 100644
index 00000000000..cf0448c8b69
--- /dev/null
+++ b/assets/js/135.cb7a50a2.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[135],{451:function(t,s,a){"use strict";a.r(s);var n=a(4),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"反向-正向代理"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#反向-正向代理"}},[t._v("#")]),t._v(" 反向/正向代理")]),t._v(" "),s("p",[t._v("在 IT 行业中, 反向代理(Reverse Proxy)是一种网络代理服务器的配置方式, 它充当了服务器和客户端之间的中间人。与传统的正向代理(Forward Proxy)不同, 正向代理是为客户端提供代理服务, 而反向代理是为服务器提供代理服务。")]),t._v(" "),s("p",[t._v("反向代理的工作原理是将客户端的请求转发到后端服务器, 并将服务器的响应返回给客户端。客户端发送请求时, 先与反向代理建立连接, 然后反向代理根据配置的规则将请求转发到后端的真实服务器上。后端服务器处理请求并返回响应, 然后反向代理将响应返回给客户端, 客户端则认为响应是直接来自于反向代理。")]),t._v(" "),s("p",[t._v("反向代理的主要作用有以下几个方面:")]),t._v(" "),s("ol",[s("li",[t._v("负载均衡: 反向代理可以根据预设的负载均衡算法将客户端请求分发到多个后端服务器, 从而平衡服务器的负载, 提高系统的性能和可靠性。")]),t._v(" "),s("li",[t._v("缓存静态内容: 反向代理可以缓存静态资源, 如图片、CSS 文件等, 以减轻后端服务器的负担, 提高响应速度。")]),t._v(" "),s("li",[t._v("SSL/TLS 加密: 反向代理可以作为 SSL/TLS 终端, 将客户端的 HTTPS 请求转发给后端服务器, 并将响应返回给客户端, 实现对传输内容的加密和安全性保护。")]),t._v(" "),s("li",[t._v("安全过滤: 反向代理可以对传入的请求进行安全过滤和防御, 例如阻止恶意请求、DDoS 攻击和 Web 应用程序漏洞等。")])]),t._v(" "),s("p",[t._v("通过使用反向代理, 可以提高网络应用的可扩展性、安全性和性能, 同时为系统管理员提供了更好的控制和管理手段。")]),t._v(" "),s("h2",{attrs:{id:"wlan0"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#wlan0"}},[t._v("#")]),t._v(" wlan0")]),t._v(" "),s("p",[t._v('"wlan0"是指在 Android 设备上表示无线局域网(Wi-Fi)接口的网络接口名称。在大多数 Android 设备中, 无线网络接口通常被标识为"wlan0", 但也有一些设备可能使用其他名称, 如"wlan1"、"wlan2"等, 这取决于设备的硬件和配置。')]),t._v(" "),s("p",[t._v('通过"wlan0"网络接口, Android 设备可以连接到 Wi-Fi 网络并进行无线通信。它负责处理与 Wi-Fi 相关的功能, 包括扫描可用网络、建立连接、传输数据等。')]),t._v(" "),s("p",[t._v("使用命令"),s("code",[t._v("adb shell ip address show wlan")]),t._v('"可以查看设备上"wlan0"接口的 IP 地址信息。这样可以获取设备当前连接的 Wi-Fi 网络的 IP 地址, 以及其他相关的网络配置信息。')]),t._v(" "),s("h2",{attrs:{id:"devops"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#devops"}},[t._v("#")]),t._v(" DevOps")]),t._v(" "),s("p",[s("strong",[t._v("DevOps 是一种软件开发和运维的实践方法")]),t._v(", 旨在通过加强开发团队和运维团队之间的协作和沟通, 实现快速、可靠的软件交付和部署。")]),t._v(" "),s("p",[t._v("DevOps 的目标是通过自动化、持续集成和持续交付等实践, 将软件开发、测试、部署和运维的过程整合起来, 从而加快软件的交付速度、提高质量, 并增强系统的稳定性和可扩展性。")]),t._v(" "),s("p",[t._v("DevOps 强调以下几个关键概念和实践:")]),t._v(" "),s("ol",[s("li",[t._v("自动化: 通过自动化工具和流程, 减少人工操作, 提高效率和一致性。")]),t._v(" "),s("li",[t._v("持续集成: 将代码频繁地集成到共享的代码库中, 通过自动化构建、测试和静态代码分析等环节, 确保代码质量和稳定性。")]),t._v(" "),s("li",[t._v("持续交付: 在持续集成的基础上, 将软件交付到生产环境中, 实现快速的软件发布和部署。")]),t._v(" "),s("li",[t._v("基础设施即代码: 使用代码和自动化工具来管理和配置基础设施, 以便快速、可靠地创建、部署和管理基础设施资源。")]),t._v(" "),s("li",[t._v("监控和日志: 通过实时监控和日志记录, 及时发现和解决系统问题, 提高系统的可用性和性能。")]),t._v(" "),s("li",[t._v("跨团队协作: 强调开发团队和运维团队之间的协作和沟通, 打破组织内的隔阂, 促进快速响应和问题解决。")])]),t._v(" "),s("p",[t._v("DevOps 的目标是通过整合开发和运维流程, 加强团队协作, 实现更高效、更可靠的软件交付和运维。它可以帮助组织更快速地响应市场需求、降低软件交付的风险和成本, 并提供更好的用户体验。")]),t._v(" "),s("h2",{attrs:{id:"数据库系统"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#数据库系统"}},[t._v("#")]),t._v(" 数据库系统")]),t._v(" "),s("blockquote",[s("p",[t._v("MongoDB、Redis 和关系型数据库是常见的数据库系统, 它们在数据存储和访问方面具有不同的特点和适用场景。")])]),t._v(" "),s("p",[t._v("MongoDB、Redis 和关系型数据库是常见的数据库系统, 它们在数据存储和访问方面具有不同的特点和适用场景。")]),t._v(" "),s("ol",[s("li",[t._v("关系型数据库(如 MySQL、PostgreSQL):")])]),t._v(" "),s("ul",[s("li",[t._v("结构化数据存储: 关系型数据库使用表格(表)来组织和存储数据, 数据以行和列的形式呈现, 并且需要定义表的结构(模式)。")]),t._v(" "),s("li",[t._v("强一致性: 关系型数据库提供强一致性, 即数据的读取和写入操作是同步和可靠的。")]),t._v(" "),s("li",[t._v("SQL 查询语言: 关系型数据库使用 SQL(Structured Query Language)进行数据查询和操作。")]),t._v(" "),s("li",[t._v("适用场景: 适合存储结构化数据, 如订单、用户信息等, 并需要进行复杂的事务处理和关系查询。")])]),t._v(" "),s("ol",{attrs:{start:"2"}},[s("li",[t._v("MongoDB:")])]),t._v(" "),s("ul",[s("li",[t._v("非结构化数据存储: MongoDB 是一种面向文档的数据库, 数据以类似 JSON 的 BSON 格式存储, 不需要预定义模式, 可以灵活地存储非结构化数据。")]),t._v(" "),s("li",[t._v("高可扩展性: MongoDB 支持水平扩展, 可以轻松处理大规模数据和高并发请求。")]),t._v(" "),s("li",[t._v("分布式数据库: MongoDB 可以作为分布式数据库, 通过副本集和分片技术实现数据的冗余备份和水平切分。")]),t._v(" "),s("li",[t._v("适用场景: 适合存储大量非结构化数据, 如日志、用户行为记录等, 并需要灵活性和可扩展性。")])]),t._v(" "),s("ol",{attrs:{start:"3"}},[s("li",[t._v("Redis:")])]),t._v(" "),s("ul",[s("li",[t._v("键值存储: Redis 是一种键值存储数据库, 数据以键值对的形式存储, 可以存储多种类型的值, 如字符串、列表、哈希表等。")]),t._v(" "),s("li",[t._v("内存数据库: Redis 将数据存储在内存中, 因此读取和写入速度非常快, 适合高速缓存和需要快速访问的应用场景。")]),t._v(" "),s("li",[t._v("高性能: Redis 具有高并发性能和低延迟, 适合处理实时数据和高频读写操作。")]),t._v(" "),s("li",[t._v("适用场景: 适合缓存、会话管理、排行榜、发布/订阅等场景, 以及需要高性能、低延迟的应用程序。")])]),t._v(" "),s("p",[t._v("总结:\n关系型数据库适合存储结构化数据和复杂的关系查询, MongoDB 适合存储非结构化数据和需要灵活性、可扩展性的场景, 而 Redis 适合高速缓存和需要快速访问的应用场景。选择合适的数据库取决于数据的特性、应用程序的需求以及性能和可扩展性的要求。在某些情况下, 这些数据库系统也可以结合使用, 以满足不同的需求。")]),t._v(" "),s("h2",{attrs:{id:"服务熔断"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#服务熔断"}},[t._v("#")]),t._v(" 服务熔断")]),t._v(" "),s("p",[t._v("服务器的熔断机制是一种用于保护系统和服务稳定性的机制。它是一种自动化的故障处理机制, 旨在避免系统由于故障或异常情况而崩溃或无法正常工作。")]),t._v(" "),s("p",[t._v("熔断机制通常在分布式系统和微服务架构中使用, 用于处理服务间的通信和依赖关系。当一个服务发生故障或异常时, 熔断机制会自动断开对该服务的调用, 并在一段时间内阻止对该服务的进一步请求。这样可以避免故障服务的连锁反应, 保护系统的稳定性和可靠性。")]),t._v(" "),s("p",[t._v("熔断机制的主要目标是:")]),t._v(" "),s("ol",[s("li",[t._v("快速失败: 在服务发生故障或异常时, 立即中断对该服务的调用, 而不是等待超时或无限等待响应。")]),t._v(" "),s("li",[t._v("避免资源浪费: 停止对故障服务的请求可以释放资源, 避免浪费服务器资源和网络带宽。")]),t._v(" "),s("li",[t._v("快速恢复: 熔断机制通常会有一个恢复时间窗口, 在该时间窗口内尝试重新调用故障服务, 以验证其是否已经恢复正常。如果故障服务恢复正常, 则继续正常的请求转发。")])]),t._v(" "),s("p",[t._v("熔断机制的实现通常通过设置一些 "),s("strong",[t._v("阈值和监控机制")]),t._v(" 来触发熔断和恢复。例如, 可以设置对服务的请求失败率、响应时间超过阈值等指标进行监控, 当这些指标超过预设的阈值时, 触发熔断操作。")]),t._v(" "),s("p",[t._v("熔断机制的好处是可以提高系统的稳定性和可用性, 避免故障服务对整个系统的影响。它还可以减少客户端对故障服务的等待时间, 提供更好的用户体验。同时, 熔断机制也可以提供实时的故障监控和告警信息, 帮助运维人员及时发现和解决问题。")]),t._v(" "),s("p",[t._v("总而言之, 服务器的熔断机制是一种自动化的故障处理机制, 用于保护系统和服务的稳定性。通过快速失败、避免资源浪费和快速恢复等措施, 它可以防止故障服务对整个系统造成连锁反应, 并提供更好的用户体验和系统可靠性。")]),t._v(" "),s("h2",{attrs:{id:"uv-vv-pv-dau-gmv"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#uv-vv-pv-dau-gmv"}},[t._v("#")]),t._v(" uv/vv/pv/dau/gmv")]),t._v(" "),s("p",[t._v("在互联网和网站分析领域中, UV、PV 和 VV 是常用的指标, 用于衡量网站流量和用户活跃度。")]),t._v(" "),s("ul",[s("li",[t._v("UV(Unique Visitor)表示独立访客数, 即在一段时间内(通常是一天), 访问网站的不同用户数量。UV 指标用于计算网站的用户数量和覆盖范围, 每个独立访客只计算一次, 无论其在该时间段内访问了多少次。")]),t._v(" "),s("li",[t._v("PV(Page View)表示页面浏览量, 即网站在一段时间内的页面浏览次数。每当用户访问一个页面, PV 就会增加一次。PV 指标用于衡量网站的流量和页面受欢迎程度, 高 PV 值通常表示用户对网站内容的浏览兴趣。")]),t._v(" "),s("li",[t._v("VV(Visit View)表示访问次数, 即在一段时间内的访问次数。VV 指标统计了用户对网站的不同访问行为, 每次用户进入网站算作一次访问, 无论期间有多少页面浏览。")]),t._v(" "),s("li",[t._v("DAU(Daily Active User)日活跃用户数量")]),t._v(" "),s("li",[t._v("MAU(monthly active users)月活跃用户人数")]),t._v(" "),s("li",[t._v("GMV(Gross Merchandise Volume,网站成交金额) 通常称为网站成交金额, 属于电商平台企业成交类指标, 主要指拍下订单的总金额, 包含付款和未付款两部分")])]),t._v(" "),s("p",[t._v("这些指标在网站分析中被广泛使用, 可以帮助分析师和网站管理员了解网站的流量情况、用户活跃度和用户行为, 从而进行数据分析和优化网站策略。")]),t._v(" "),s("h2",{attrs:{id:"faas"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#faas"}},[t._v("#")]),t._v(" FaaS")]),t._v(" "),s("blockquote",[s("p",[t._v("FaaS(Function as a Service)。 更多介绍 "),s("a",{attrs:{href:"https://cloud.tencent.com/developer/article/2218051?from=15425",target:"_blank",rel:"noopener noreferrer"}},[t._v("点击"),s("OutboundLink")],1)])]),t._v(" "),s("p",[t._v("FaaS 模型使研发人员能够将更多的精力集中在编写业务逻辑上, 而不必担心底层基础设施的维护。这种模型的弹性和自动化能力也使其适用于各种不同类型的应用, 尤其是需要应对波动负载的应用。")]),t._v(" "),s("RText",{attrs:{text:"FaaS 具有如下特性"}}),t._v(" "),s("ul",[s("li",[t._v("编码简单、轻量 - 可基于平台为各语言(Node.js、Python、Shell、Java )定义的规范编写代码, 快速开发业务逻辑")]),t._v(" "),s("li",[t._v("扩展性好 - 支持自定义运行时(Custom Runtime), 并通过层, 可方便植入业务依赖, 无须自定义镜像")]),t._v(" "),s("li",[t._v("内置基础组件 - 内置 Dubbo、HTTP、MySQL、Redis、Leo 等基础组件访问, 按需使用")]),t._v(" "),s("li",[t._v("较高的资源利用率 - 接入弹性系统, 可按需扩容计算资源, 一些场景下支持服务资源缩容到 0 实例")]),t._v(" "),s("li",[t._v("安全可靠 - 支持在不同可用区部署, 支持跨区跨云容灾, 提供极高的容错性")]),t._v(" "),s("li",[t._v("支持 HTTP 触发 - 支持各类 LB 触发, 流量配置策略灵活")]),t._v(" "),s("li",[t._v("MQ 消息触发 - 支持 Tiger 消息触发, 无须关注消息系统的连接配置细节, 天然跨语言")]),t._v(" "),s("li",[t._v("开发工具支持 - 支持在线代码编辑和 IDE 插件(VSCode \\ Intellij), 并通过 faas-cli 支持常用组件(如)的配置自动生产")]),t._v(" "),s("li",[t._v("和常用基础服务联通 - 如水滴, ABTest, 华山, 衡山等")])]),t._v(" "),s("RText",{attrs:{text:"调用和启动流程"}}),t._v(" "),s("p",[t._v("FaaS(Function as a Service)调用和启动流程通常包括以下步骤:")]),t._v(" "),s("ol",[s("li",[s("p",[t._v("事件触发: FaaS 函数的启动通常是由外部事件触发的。这些事件可以来自各种来源, 例如 HTTP 请求、消息队列、存储桶的变化、定时触发器等。")])]),t._v(" "),s("li",[s("p",[t._v("事件传递: 当事件触发时, 相应的事件数据将传递给 FaaS 平台。")])]),t._v(" "),s("li",[s("p",[t._v('函数初始化: 如果尚未有活动的函数实例(或者函数实例被回收了), FaaS 平台将启动新的函数实例。这个过程被称为 "冷启动"。在冷启动过程中, 平台会初始化函数的运行时环境, 加载函数代码, 配置运行环境等。这一过程的时间在通常情况下很短, 但在某些情况下可能会有延迟。')])]),t._v(" "),s("li",[s("p",[t._v("执行函数: 一旦函数实例启动并初始化完成, 平台将事件数据传递给函数的处理程序(handler)。函数的处理程序开始执行业务逻辑, 根据事件数据进行处理。")])]),t._v(" "),s("li",[s("p",[t._v("返回结果: 函数执行完成后, 可以生成响应并将其返回给触发事件的来源。响应可以是 HTTP 响应、消息队列消息、存储桶的变化等, 具体取决于事件的类型。")])]),t._v(" "),s("li",[s("p",[t._v('回收函数实例: 在某些 FaaS 平台上, 函数实例可以在一段时间后回收, 以节省资源。这个过程被称为 "回收"。如果函数实例被回收, 下次触发事件时需要再次进行初始化。')])]),t._v(" "),s("li",[s("p",[t._v("日志和监控: FaaS 平台通常提供了日志和监控功能, 以便开发人员可以跟踪函数的执行情况, 诊断问题并监视性能。")])])]),t._v(" "),s("p",[t._v("整个过程是自动的, 开发人员只需关注编写函数的业务逻辑, 而不必担心底层的服务器、容器或虚拟机的管理。这种模型具有高度的弹性, 适用于需要快速响应事件的应用程序, 同时可以根据负载自动扩展和回收资源。")]),t._v(" "),s("h2",{attrs:{id:"染色概念"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#染色概念"}},[t._v("#")]),t._v(" 染色概念")]),t._v(" "),s("blockquote",[s("p",[t._v("uid 染色")])]),t._v(" "),s("p",[t._v("通过 UID(User ID)染色是一种常见的技术手段, 用于在公司的平台或系统中对用户进行标识、分组或定制化处理。UID 是唯一标识用户的标识符, 每个用户在系统中都有一个唯一的 UID。")]),t._v(" "),s("p",[t._v("UID 染色的过程通常包括以下几个步骤:")]),t._v(" "),s("ul",[s("li",[s("p",[t._v("用户注册或登录: 当用户在公司的平台上注册或登录时, 系统会为其分配一个唯一的 UID。")])]),t._v(" "),s("li",[s("p",[t._v("UID 绑定: 在用户注册或登录后, 系统将 UID 与用户的个人信息进行绑定, 以便后续识别和操作。")])]),t._v(" "),s("li",[s("p",[t._v("UID 映射: 公司的平台会根据业务需求, 将特定的功能、服务或内容与特定的 UID 进行映射。这样可以针对不同的用户群体进行个性化处理。")])]),t._v(" "),s("li",[s("p",[t._v("染色规则定义: 在 UID 染色过程中, 公司会定义一系列染色规则或条件。这些规则可能基于用户的属性、行为、偏好等信息, 用于将用户划分为不同的群体或标签。")])]),t._v(" "),s("li",[s("p",[t._v("个性化处理: 通过 UID 染色, 公司可以根据染色规则将用户分配到相应的群体或标签中, 并针对不同群体提供个性化的功能、服务或内容。例如, 向特定群体的用户展示特定的推荐内容、定制化的界面布局等。")])])]),t._v(" "),s("p",[t._v("UID 染色可以帮助公司更好地理解和满足用户的需求, 提供更个性化、精准的用户体验。它可以用于用户分析、精准营销、A/B 测试等场景, 帮助公司优化产品和服务, 提升用户满意度和业务效果。")]),t._v(" "),s("h2",{attrs:{id:"websocket-vs-socket"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#websocket-vs-socket"}},[t._v("#")]),t._v(" websocket VS socket")]),t._v(" "),s("blockquote",[s("p",[t._v("WebSocket 和 Socket 都是用于在网络上进行通信的技术, 但它们在工作方式和应用场景上有很大的区别")])]),t._v(" "),s("RText",{attrs:{text:"WebSocke"}}),t._v(" "),s("ul",[s("li",[t._v("WebSocket 是一种基于 HTTP 协议的通信协议, 它允许客户端和服务器之间建立持久连接, 以便双向实时通信。(应用层(Application Layer)的通信协议)")]),t._v(" "),s("li",[t._v("WebSocket 协议是一种高级协议, 构建在 HTTP 协议之上, 因此可以穿越大多数防火墙和代理服务器。")]),t._v(" "),s("li",[t._v("WebSocket 通信是事件驱动的, 它允许服务器主动向客户端发送消息, 而不需要客户端发起请求。")]),t._v(" "),s("li",[t._v("WebSocket 通信通常用于实时性要求高的应用, 如在线游戏、在线聊天、实时监控等。")])]),t._v(" "),s("RText",{attrs:{text:"Socket"}}),t._v(" "),s("ul",[s("li",[t._v("Socket 是一种低级别的通信协议, 它提供了一种在网络上建立连接并进行数据传输的通用方式。(位于传输层(Transport Layer))")]),t._v(" "),s("li",[t._v("Socket 通信需要在客户端和服务器之间建立连接, 然后通过套接字发送和接收数据。")]),t._v(" "),s("li",[t._v("Socket 通信可以用于各种类型的应用, 包括文件传输、远程控制、数据采集等。")]),t._v(" "),s("li",[t._v("Socket 通信通常需要客户端主动发起连接, 服务器接受连接请求, 因此它通常是一种请求响应型的通信。")])]),t._v(" "),s("RText",{attrs:{text:"总结"}}),t._v(" "),s("p",[t._v("WebSocket 适用于实时性要求高的应用, 它提供了一种高级别、事件驱动的通信方式, 适用于构建实时互动性应用。Socket 通信更灵活, 适用于各种不同类型的应用, 但它通常需要更多的管理和处理, 适用于构建自定义通信协议或处理特定的通信需求。选择 WebSocket 还是 Socket 取决于您的应用需求和设计。")]),t._v(" "),s("h2",{attrs:{id:"websocket-的实现方式"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#websocket-的实现方式"}},[t._v("#")]),t._v(" websocket 的实现方式")]),t._v(" "),s("p",[t._v("从 "),s("a",{attrs:{href:"https://github.com/xkcoding/spring-boot-demo/tree/master/demo-websocket",target:"_blank",rel:"noopener noreferrer"}},[t._v("demo-websocket"),s("OutboundLink")],1),t._v(" 示例中看出.")]),t._v(" "),s("ul",[s("li",[t._v("前端可以基于 sockJs(浏览器中处理 WebSocket 连接) 使用 "),s("a",{attrs:{href:"https://juejin.cn/post/7025162016985710599",target:"_blank",rel:"noopener noreferrer"}},[t._v("STOMP"),s("OutboundLink")],1),t._v(" 协议进行")]),t._v(" "),s("li",[t._v("后端使用 "),s("code",[t._v("org.springframework.boot:spring-boot-starter-websocket")]),t._v(" 来实现")])]),t._v(" "),s("h2",{attrs:{id:"dao-data-access-object"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#dao-data-access-object"}},[t._v("#")]),t._v(" Dao(Data Access Object)")]),t._v(" "),s("p",[t._v("是一种模式, 用于在应用程序和数据存储之间提供一个抽象层, 以简化数据存储访问。它通常是用于创建、更新、检索和删除数据的方法的集合, 并且它涵盖了数据存储的所有细节, 以便应用程序可以专注于业务逻辑。因此, 它是数据操作层的重要组成部分。")]),t._v(" "),s("h2",{attrs:{id:"mapper"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mapper"}},[t._v("#")]),t._v(" mapper")]),t._v(" "),s("p",[t._v('在 Java 中, "Mapper" 是一个常见的术语, 通常用于描述一种用于将数据从一种形式映射到另一种形式的工具或组件。在不同的上下文中, "Mapper" 可以表示不同的含义, 以下是其中一些常见的用法:')]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("数据访问对象(Data Access Object)Mapper")]),t._v(":")])]),t._v(" "),s("p",[t._v("在数据访问层中, Mapper 通常是指数据访问对象(DAO)的一部分。它用于将数据库表的记录(通常是关系型数据库表)映射到 Java 对象, 或者将 Java 对象映射到数据库表。这是一种常见的 ORM(对象关系映射)模式的实现。例如, 在使用 Hibernate、MyBatis 或 JPA 等持久化框架时, 通常会编写 Mapper 接口或配置文件来定义对象到数据库表的映射关系。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// MyBatis Mapper Interface")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("UserMapper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getUserById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("insertUser")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br")])]),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("对象映射器(Object Mapper)")]),t._v(":")])]),t._v(" "),s("p",[t._v("在处理不同数据格式(例如 JSON、XML)的时候, 对象映射器通常用于将数据转换为 Java 对象或将 Java 对象转换为数据。一些流行的 Java 对象映射器包括 Jackson(用于 JSON)、JAXB(Java Architecture for XML Binding, 用于 XML)、Dozer 等。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 Jackson ObjectMapper 将 JSON 字符串转换为 Java 对象")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ObjectMapper")]),t._v(" objectMapper "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ObjectMapper")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" user "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" objectMapper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("readValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("jsonString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br")])]),s("ol",{attrs:{start:"3"}},[s("li",[s("strong",[t._v("模型-视图映射器(Model-View Mapper)")]),t._v(":")])]),t._v(" "),s("p",[t._v("在 Web 应用程序中, 模型-视图映射器通常用于将应用程序的模型数据映射到视图层(通常是 HTML 或其他视图模板)以进行渲染。一些 Java Web 框架(例如 Spring MVC)提供了视图解析器和模型映射器, 用于处理这种类型的映射。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Spring MVC Controller method with Model-View Mapping")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@GetMapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/user/{id}"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getUser")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@PathVariable")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"id"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Model")]),t._v(" model"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" user "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" userService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getUserById")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n model"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addAttribute")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user-profile"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// View name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br")])]),s("ol",{attrs:{start:"4"}},[s("li",[s("strong",[t._v("其他映射器")]),t._v(":")])]),t._v(" "),s("p",[t._v("在不同领域中, Mapper 可能具有不同的含义。例如, 图形映射器用于将图像的像素映射到屏幕上, 地图映射器用于将地理坐标映射到地图上, 等等。")]),t._v(" "),s("p",[t._v('总之, "Mapper" 是一个通用的术语, 它描述了一种将数据从一种形式映射到另一种形式的工具或组件。在不同的上下文中, 它可以表示不同类型的映射, 包括数据访问、对象映射、模型-视图映射以及其他领域中的映射。在 Java 中, 您可以使用各种库和框架来实现这些映射。')]),t._v(" "),s("h2",{attrs:{id:"jdbc-java-database-connectivity"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#jdbc-java-database-connectivity"}},[t._v("#")]),t._v(" JDBC(Java Database Connectivity)")]),t._v(" "),s("ul",[s("li",[t._v("定义: JDBC 是 Java 用于与关系型数据库交互的标准 API。它允许 Java 应用程序与数据库建立连接、执行 SQL 查询、插入、更新和删除数据。")]),t._v(" "),s("li",[t._v("用途: JDBC 用于直接管理数据库连接和执行 SQL 操作。它是一个底层的、面向关系型数据库的 API。开发人员需要手动编写 SQL 语句, 并处理数据库连接、事务等细节。")]),t._v(" "),s("li",[t._v("工作方式: JDBC 提供了一组接口和类, 允许 Java 应用程序执行以下操作:\n"),s("ul",[s("li",[t._v("建立数据库连接")]),t._v(" "),s("li",[t._v("创建和执行 SQL 语句")]),t._v(" "),s("li",[t._v("处理结果集")]),t._v(" "),s("li",[t._v("管理事务")])])]),t._v(" "),s("li",[t._v("示例: 以下是一个简单的 JDBC 示例, 用于连接到数据库并执行查询操作:")])]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sql"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sql"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DriverManager")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sql"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResultSet")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("sql"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Statement")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("JDBCDemo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.mysql.jdbc.Driver"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Connection")]),t._v(" connection "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DriverManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getConnection")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"jdbc:mysql://localhost:3306/mydb"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"username"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Statement")]),t._v(" statement "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" connection"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createStatement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ResultSet")]),t._v(" resultSet "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" statement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("executeQuery")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SELECT * FROM users"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resultSet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("next")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("System")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("println")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resultSet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"username"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n resultSet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n statement"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n connection"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("close")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Exception")]),t._v(" e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n e"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("printStackTrace")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br"),s("span",{staticClass:"line-number"},[t._v("17")]),s("br"),s("span",{staticClass:"line-number"},[t._v("18")]),s("br"),s("span",{staticClass:"line-number"},[t._v("19")]),s("br"),s("span",{staticClass:"line-number"},[t._v("20")]),s("br"),s("span",{staticClass:"line-number"},[t._v("21")]),s("br"),s("span",{staticClass:"line-number"},[t._v("22")]),s("br"),s("span",{staticClass:"line-number"},[t._v("23")]),s("br")])]),s("h2",{attrs:{id:"jpa-java-persistence-api"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#jpa-java-persistence-api"}},[t._v("#")]),t._v(" JPA(Java Persistence API)")]),t._v(" "),s("ul",[s("li",[t._v("定义: JPA 是 Java 的持久化 API, 用于将 Java 对象映射到数据库表。它提供了一种更高级别、面向对象的方式来处理持久化, 而不需要编写大量的 SQL 代码。")]),t._v(" "),s("li",[t._v("用途: JPA 用于简化数据持久化的过程, 提供了对象关系映射(ORM)的功能。它允许开发人员通过定义实体类和注解来描述数据库表和对象之间的映射, 而不需要编写复杂的 SQL 查询。")]),t._v(" "),s("li",[t._v("工作方式: JPA 通过注解或 XML 配置文件来描述实体类与数据库表之间的映射关系。开发人员可以使用 JPA 提供的 API 来执行 CRUD(创建、读取、更新、删除)操作, 而不需要编写原始 SQL 语句。")]),t._v(" "),s("li",[t._v("示例: 以下是一个简单的 JPA 示例, 用于定义实体类和执行查询操作:")])]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("javax"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("persistence"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Entity")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Table")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"users"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Id")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@GeneratedValue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("strategy "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("GenerationType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("IDENTITY")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Long")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Column")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"username"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" username"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Getters and setters")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用 JPA 查询")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EntityManagerFactory")]),t._v(" emf "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Persistence")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createEntityManagerFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"my-persistence-unit"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EntityManager")]),t._v(" em "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" emf"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createEntityManager")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("TypedQuery")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" query "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" em"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createQuery")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"SELECT u FROM User u WHERE u.username = :username"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nquery"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setParameter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"username"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"john"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("List")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("User")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" users "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" query"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getResultList")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br"),s("span",{staticClass:"line-number"},[t._v("17")]),s("br"),s("span",{staticClass:"line-number"},[t._v("18")]),s("br"),s("span",{staticClass:"line-number"},[t._v("19")]),s("br"),s("span",{staticClass:"line-number"},[t._v("20")]),s("br"),s("span",{staticClass:"line-number"},[t._v("21")]),s("br"),s("span",{staticClass:"line-number"},[t._v("22")]),s("br")])]),s("h2",{attrs:{id:"jwt"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#jwt"}},[t._v("#")]),t._v(" jwt")]),t._v(" "),s("p",[t._v("JWT(JSON Web Token)是一种用于在网络应用之间安全传输信息的开放标准(RFC 7519)。它通过使用数字签名或加密来验证信息的可信性, 通常用于实现用户身份验证和授权。JWT 认证的工作原理如下:")]),t._v(" "),s("ul",[s("li",[t._v("用户登录: 用户通过提供有效的凭证(通常是用户名和密码)来登录应用程序。")]),t._v(" "),s("li",[t._v("生成 JWT: 一旦用户成功登录, 服务器将生成一个 JWT。JWT 通常包含以下信息:\n"),s("ul",[s("li",[t._v("用户标识(例如用户 ID 或用户名)")]),t._v(" "),s("li",[t._v("过期时间(JWT 的有效期)")]),t._v(" "),s("li",[t._v("其他自定义的声明(例如用户角色、权限等)\n服务器使用一个密钥来签名 JWT, 以确保它的完整性和真实性。")])])]),t._v(" "),s("li",[t._v("将 JWT 发送给客户端: 生成的 JWT 将被发送回客户端, 通常存储在客户端的 Cookie 或本地存储中。")]),t._v(" "),s("li",[t._v("客户端请求受保护资源: 当客户端尝试访问需要身份验证的资源时, 它将在请求中包含 JWT。通常, JWT 放在请求的授权头(Authorization Header)中, 以 Bearer Token 的形式传递。")]),t._v(" "),s("li",[t._v("服务器验证 JWT: 服务器收到包含 JWT 的请求后, 将验证 JWT 的签名以确保其完整性和真实性。如果 JWT 有效且未过期, 则服务器将允许访问受保护的资源。")]),t._v(" "),s("li",[t._v("响应受保护资源: 如果 JWT 有效, 服务器将响应客户端请求并提供受保护资源。")])]),t._v(" "),s("hr"),t._v(" "),s("RText",{attrs:{text:"JWT 认证的优点包括"}}),t._v(" "),s("ul",[s("li",[t._v("无状态: JWT 本身包含了所有必要的信息, 服务器不需要存储用户的会话信息。这使得应用程序更容易扩展, 因为它不需要依赖于特定的会话存储机制。")]),t._v(" "),s("li",[t._v("安全性: JWT 可以使用数字签名来保护数据的完整性, 也可以使用加密来保护数据的隐私。这使得它非常适合在不信任的网络中进行安全通信。")]),t._v(" "),s("li",[t._v("跨域支持: JWT 可以轻松地在不同域之间传递, 因为它可以通过 HTTP 请求头进行传递。")]),t._v(" "),s("li",[t._v("可扩展性: JWT 允许包含自定义声明, 可以用于存储用户角色、权限和其他自定义信息。")])]),t._v(" "),s("p",[t._v("需要注意的是, JWT 也有一些潜在的安全风险, 例如, 如果密钥丢失或泄露, 攻击者可能会伪造有效的 JWT。因此, 在实施 JWT 认证时, 必须采取适当的安全措施来保护密钥和令牌。此外, JWT 通常不适用于存储大量敏感信息, 因为它们可以在客户端解码。")]),t._v(" "),s("h2",{attrs:{id:"swagger3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#swagger3"}},[t._v("#")]),t._v(" Swagger3")]),t._v(" "),s("p",[t._v("Swagger 3.0 是一种用于定义、构建和文档化 RESTful API 的规范。它使开发人员能够创建具有可读性和易于理解的 API 文档, 同时还提供了工具和库来自动生成客户端 SDK 和服务器存根。以下是如何使用 Swagger 3.0 来定义和文档化 Java 中的 RESTful API 的基本步骤:")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("添加 Swagger 依赖")]),t._v(":")])]),t._v(" "),s("p",[t._v("首先, 您需要在 Java 项目中添加 Swagger 的依赖库。这通常包括 "),s("code",[t._v("swagger-core")]),t._v(" 和 "),s("code",[t._v("swagger-ui")]),t._v("。您可以使用 Maven 或 Gradle 来添加这些依赖。\n使用 Maven, 您可以将以下依赖添加到您的 pom.xml 文件中:")]),t._v(" "),s("div",{staticClass:"language-xml line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("io.swagger.core.v3"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("swagger-core"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("2.1.10"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("org.webjars"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("swagger-ui"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("3.51.3"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br")])]),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("创建 API 文档")]),t._v(":")])]),t._v(" "),s("p",[t._v("在 Java 代码中, 您可以使用 Swagger 注解来描述您的 RESTful API。Swagger 提供了一些常用的注解, 如 "),s("code",[t._v("@Api")]),t._v(", "),s("code",[t._v("@ApiOperation")]),t._v(", "),s("code",[t._v("@ApiParam")]),t._v(" 等, 用于定义 API 的信息、操作和参数。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("io"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("swagger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotations"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("springframework"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("web"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("bind"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotation"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RestController")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequestMapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Api")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tags "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Sample API"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SampleController")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@GetMapping")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/hello"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ApiOperation")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Say hello"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sayHello")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@RequestParam")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" defaultValue "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"World"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@ApiParam")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Name to greet"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" name\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hello, "')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"!"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br")])]),s("ol",{attrs:{start:"3"}},[s("li",[s("strong",[t._v("配置 Swagger")]),t._v(":")])]),t._v(" "),s("p",[t._v("在您的 Java 应用程序中, 您需要配置 Swagger 来生成 API 文档。这通常涉及创建一个 Swagger 配置类, 并将其与 Spring Boot 或其他 Java 框架集成。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("springframework"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("context"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotation"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("springfox"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("documentation"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("spring"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("web"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("plugins"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("springfox"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("documentation"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("swagger2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotations"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Configuration")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@EnableSwagger2")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("SwaggerConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Bean")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Docket")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("api")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Docket")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DocumentationType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SWAGGER_2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("select")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("apis")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("RequestHandlerSelectors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("basePackage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.example"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("paths")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("PathSelectors")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br")])]),s("ol",{attrs:{start:"4"}},[s("li",[s("strong",[t._v("访问 Swagger UI")]),t._v(":")])]),t._v(" "),s("p",[t._v("启动您的 Java 应用程序后, 您可以在浏览器中访问 Swagger UI, 通常位于 /swagger-ui.html。这将显示一个可交互的 API 文档, 允许您浏览和测试您的 API。\n例如: "),s("a",{attrs:{href:"http://localhost:8080/swagger-ui.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("http://localhost:8080/swagger-ui.html"),s("OutboundLink")],1)]),t._v(" "),s("p",[t._v("这些是使用 Swagger 3.0(OpenAPI 3.0)来定义和文档化 Java RESTful API 的基本步骤。通过注解和配置, 您可以更详细地定义您的 API, 包括操作、请求和响应。Swagger 将根据这些信息生成详细的 API 文档, 并提供交互式界面来测试 API。这有助于团队更好地理解和使用您的 API。")]),t._v(" "),s("h2",{attrs:{id:"restful-api"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#restful-api"}},[t._v("#")]),t._v(" RESTful API")]),t._v(" "),s("p",[t._v("RESTful API(Representational State Transfer API)是一种基于 HTTP 协议的应用程序编程接口(API)设计风格, 它采用了一组约定和约束, 旨在使网络应用程序更加简单、可伸缩和易于扩展。RESTful API 的设计风格是由 Roy Fielding 在他的博士论文中首次提出的, 并成为了构建分布式网络应用的一种常见方式。")]),t._v(" "),s("p",[t._v("以下是 RESTful API 的主要特点和原则:")]),t._v(" "),s("ol",[s("li",[s("p",[s("strong",[t._v("资源(Resources)")]),t._v(": 在 RESTful API 中, 一切都是资源, 每个资源都有一个唯一的标识符(通常是 URL)。资源可以是物理实体(例如数据库记录)、虚拟实体(例如计算机服务)或抽象概念(例如订单或用户)。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("HTTP 动词")]),t._v(": RESTful API 使用 HTTP 方法来执行操作。常见的 HTTP 动词包括 GET(获取资源)、POST(创建资源)、PUT(更新资源)和 DELETE(删除资源)。这些动词与资源的 CRUD 操作(创建、读取、更新、删除)相对应。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("状态无关性(Statelessness)")]),t._v(": 每个 HTTP 请求都包含了足够的信息, 服务器不需要保存客户端的状态。每个请求都应该是独立的, 这样可以更容易实现负载均衡和横向扩展。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("统一接口(Uniform Interface)")]),t._v(": RESTful API 的接口应该是简单、一致和易于理解的。这使得客户端能够轻松地与不同的服务进行交互。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("资源的表述(Resource Representation)")]),t._v(": 资源的表述是资源的具体数据, 通常以 JSON 或 XML 格式返回给客户端。客户端可以使用这些表述来操作资源。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("无状态通信(Stateless Communication)")]),t._v(": 每个请求都应该包含足够的信息, 以便服务器可以理解它, 而不需要查看之前的请求。这使得 RESTful API 易于缓存和代理。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("自我描述性(Self-Descriptive Messages)")]),t._v(": 每个请求和响应都应该包含足够的信息, 以便客户端和服务器都能理解它, 而不需要事先了解上下文。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("按需响应(On-Demand Response)")]),t._v(": 客户端决定何时请求资源, 服务器不会自动推送数据。这使得客户端可以按需获取数据, 减少不必要的网络流量。")])])]),t._v(" "),s("p",[t._v("RESTful API 通常使用 URL 来唯一标识资源, 使用 HTTP 方法来执行操作, 使用状态码来表示操作的结果。它们可以通过 URL 参数、HTTP 头部和请求体来传递数据, 通常使用 JSON 或 XML 格式返回数据。")]),t._v(" "),s("p",[t._v("总之, RESTful API 是一种简单、可伸缩和易于理解的 API 设计风格, 广泛用于构建 Web 服务和分布式系统。它的设计原则强调资源、状态无关性和统一接口, 使得开发者能够构建灵活和可维护的应用程序。")]),t._v(" "),s("h2",{attrs:{id:"aspectj-实现-aop"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#aspectj-实现-aop"}},[t._v("#")]),t._v(" AspectJ 实现 AOP")]),t._v(" "),s("p",[t._v("在 Spring 中, 您可以使用 AspectJ 来实现面向切面编程(AOP)。AspectJ 是一个强大的 AOP 框架, 它可以与 Spring 集成以实现更复杂的横切关注点。以下是在 Spring 中使用 AspectJ 来实现 AOP 的一般步骤:")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("添加 AspectJ 依赖")]),t._v(": 首先, 您需要在项目中添加 AspectJ 的依赖。如果使用 Maven, 可以在 pom.xml 中添加以下依赖:")])]),t._v(" "),s("div",{staticClass:"language-xml line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("org.aspectj"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("aspectjweaver"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("1.9.7"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("\x3c!-- 使用合适的版本 --\x3e")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br")])]),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("创建切面类")]),t._v(": 创建一个 Java 类来充当您的切面。切面类通常包含各种通知(Advice), 以定义在何时和何地执行横切关注点。一个简单的切面类示例:")])]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("aspectj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lang"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotation"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Aspect")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("aspectj"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lang"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotation"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Before")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("springframework"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("stereotype"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Component")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Aspect")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Component")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyAspect")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Before")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"execution(* com.example.service.*.*(..))"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("beforeServiceMethods")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 在service包中的所有方法执行前执行此通知")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("System")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("out"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("println")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Before executing a service method..."')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br")])]),s("p",[t._v("在上面的示例中, "),s("code",[t._v("@Aspect")]),t._v(" 注解将该类标记为一个切面, @Before 注解定义了一个前置通知, 它在 com.example.service 包中的所有方法执行前执行。")]),t._v(" "),s("ol",{attrs:{start:"3"}},[s("li",[s("strong",[t._v("配置 AspectJ 支持")]),t._v(": 在 Spring 配置文件中启用 AspectJ 支持。您可以使用 XML 配置或基于 Java 的配置来完成这一步。")])]),t._v(" "),s("ul",[s("li",[t._v("XML 配置示例:")])]),t._v(" "),s("div",{staticClass:"language-xml line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("aop:")]),t._v("aspectj-autoproxy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br")])]),s("ul",[s("li",[t._v("Java 配置示例:")])]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("springframework"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("context"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("annotation"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("EnableAspectJAutoProxy")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Configuration")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@EnableAspectJAutoProxy")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AppConfig")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 其他配置...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br")])]),s("ol",{attrs:{start:"4"}},[s("li",[s("p",[s("strong",[t._v("在目标 Bean 上应用切面")]),t._v(": 确保您的切面生效, 需要在目标 Bean 上应用切面。您可以使用 "),s("code",[t._v("@Component")]),t._v(" 或其他 Spring 组件扫描注解来确保目标 Bean 被 Spring 管理。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("运行应用程序")]),t._v(": 启动您的 Spring 应用程序。AspectJ 将会自动拦截匹配切点表达式的方法, 并在适当的时候执行通知。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("验证 AOP 效果")]),t._v(": 调用目标 Bean 上的方法, 然后检查切面的通知是否按预期执行。")])])]),t._v(" "),s("p",[t._v("这些是使用 AspectJ 在 Spring 中实现 AOP 的一般步骤。您可以根据具体的需求和场景定义不同类型的通知(前置、后置、环绕等)以及切点表达式来捕获不同的横切关注点。AspectJ 提供了丰富的语法和功能, 以满足各种 AOP 需求。")]),t._v(" "),s("hr"),t._v(" "),s("p",[s("strong",[t._v("AspectJ 的工作原理涉及以下几个关键概念和组件")])]),t._v(" "),s("ul",[s("li",[s("p",[t._v("切面(Aspect): 切面是一个模块, 它包含了一组通知(Advice)和切点(Pointcut)。通知定义了在何时和何地执行横切关注点, 而切点定义了在何处执行通知。")])]),t._v(" "),s("li",[s("p",[t._v("通知(Advice): 通知是切面的具体行为。AspectJ 支持多种类型的通知, 包括前置通知(Before)、后置通知(After)、环绕通知(Around)等。通知是在切点处执行的代码片段。")])]),t._v(" "),s("li",[s("p",[t._v("切点(Pointcut): 切点是一个表达式, 它定义了在程序中的哪些位置执行通知。切点可以使用 AspectJ 的切点表达式语言来定义, 例如, 执行某个包中的所有方法或者执行某个特定注解标记的方法。")])]),t._v(" "),s("li",[s("p",[t._v("连接点(Join Point): 连接点是程序执行过程中的一个具体点, 例如方法的调用、方法的执行、对象的创建等。连接点是切点的实际实例, 它是通知实际执行的地方。")])]),t._v(" "),s("li",[s("p",[t._v("织入(Weaving): 织入是将切面与应用程序的目标代码连接在一起的过程。在编译时、类加载时或运行时, AspectJ 可以将切面织入到目标代码中, 以执行通知。")])]),t._v(" "),s("li",[s("p",[t._v("目标对象(Target Object): 目标对象是应用程序中的原始对象, 它可能包含横切关注点。切面可以通过通知来影响目标对象的行为。")])])]),t._v(" "),s("p",[s("strong",[t._v("AspectJ 的工作原理可以概括为以下几个步骤")])]),t._v(" "),s("ol",[s("li",[s("p",[t._v("定义切面: 开发人员定义一个切面, 其中包含了通知和切点的定义。")])]),t._v(" "),s("li",[s("p",[t._v("编写切点表达式: 开发人员编写切点表达式, 以指定在何处执行通知。切点表达式可以选择性地使用各种条件, 如方法名称、方法参数、注解等。")])]),t._v(" "),s("li",[s("p",[t._v("织入切面: AspectJ 在适当的时机将切面织入到目标代码中。这可以在编译时、类加载时或运行时进行。")])]),t._v(" "),s("li",[s("p",[t._v("执行通知: 当程序执行达到切点时, AspectJ 执行与切点相关联的通知。通知可以在切点之前、之后或代替切点执行。")])])]),t._v(" "),s("h2",{attrs:{id:"cdn-p2p-和-pcdn"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#cdn-p2p-和-pcdn"}},[t._v("#")]),t._v(" CDN, p2p 和 PCDN")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("CDN")]),t._v(": 即 Content Delivery Network, 中文全称为内容分发网络。")]),t._v(" "),s("li",[s("code",[t._v("P2P")]),t._v(": 即 Peer-To-Peer, 应用于互联网上, 是指一种点对点传输的网络结构, 形象地描述为图1这样一个搭档式的组织结构。如同人与人之间的交流, 每个节点(也就是搭档)之间地位相同, 又相互独立, 处于对等状态, 不以个人为中心")]),t._v(" "),s("li",[s("code",[t._v("PCDN")]),t._v(": 在 CDN 产品的基础上融合新一代 P2P 技术, 充分利用边缘网络海量碎片化的计算、存储、网络等闲置资源构建低成本、高质量的内容分发网络服务。通过创新的分发网络优化技术和精准的智能调度系统, 在为用户提供稳定、高质量的分发加速服务的同时, 显著降低分发成本。")])]),t._v(" "),s("h2",{attrs:{id:"常用依赖"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#常用依赖"}},[t._v("#")]),t._v(" 常用依赖")]),t._v(" "),s("h2",{attrs:{id:"lombok"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#lombok"}},[t._v("#")]),t._v(" lombok")]),t._v(" "),s("blockquote",[s("p",[s("code",[t._v("org.projectlombok:lombok")]),t._v(":Lombok 是一个 Java 库, 它通过使用注解来减少 Java 代码的样板代码, 从而简化 Java 开发")])]),t._v(" "),s("p",[s("code",[t._v("@Data")]),t._v("注解是 Lombok 库中的一个注解, 它可以自动生成 Java 类的通用方法, 如 toString、equals、hashCode 和"),s("code",[t._v("Getter/Setter")]),t._v("方法等。然而, 如果您想要使用"),s("code",[t._v("@Data")]),t._v("注解生成 Getter 方法, 但不生成 Setter 方法, 可以使用@Getter 注解来实现这一目标。以下是示例:")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lombok"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Data")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("lombok"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Getter")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyData")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" field1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 使用@Getter注解生成Getter方法, 但不生成Setter方法")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Getter")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" field2"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br")])]),s("p",[t._v("在这个示例中, "),s("code",[t._v("@Data")]),t._v("注解用于自动生成通用方法, 包括 Getter 方法。然而, 通过在 field2 上使用@Getter 注解, 我们告诉 Lombok 只生成 Getter 方法, 而不生成 Setter 方法。")]),t._v(" "),s("p",[t._v("这样, 对于 field1, "),s("code",[t._v("@Data")]),t._v("会生成 Getter 和 Setter 方法, 而对于 field2, 只会生成 Getter 方法。")]),t._v(" "),s("p",[t._v("请确保您已经将 Lombok 库添加到项目的依赖中, 以便使用这些注解。通常, 您需要在项目的 build.gradle 或 pom.xml 文件中添加 Lombok 的依赖。")]),t._v(" "),s("p",[s("strong",[t._v("声明")])]),t._v(" "),s("code-group",[s("code-block",{attrs:{title:"gradle",active:""}},[s("div",{staticClass:"language-groovy line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-groovy"}},[s("code",[t._v("implementation "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'org.projectlombok:lombok:1.18.22'")]),t._v("\nannotationProcessor "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'org.projectlombok:lombok:1.18.22'")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br")])])]),t._v(" "),s("code-block",{attrs:{title:"maven"}},[s("div",{staticClass:"language-groovy line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-groovy"}},[s("code",[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("dependency"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("groupId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("projectlombok"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("groupId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("artifactId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("lombok"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("artifactId"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("optional"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("optional"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("dependency"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br")])])])],1),t._v(" "),s("p",[t._v("在 maven 申明中, 如果"),s("code",[t._v("@Data")]),t._v("注解不生成相关方法, 可以尝试。 "),s("code",[t._v("reload maven")]),t._v(" 根据 IDE 的提示操作")]),t._v(" "),s("h2",{attrs:{id:"logback"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#logback"}},[t._v("#")]),t._v(" logback")]),t._v(" "),s("p",[t._v("Logback 是一个开源的日志框架, 用于在 Java 应用程序中记录日志。它是 log4j 框架的继承者, 并提供了更多的功能和性能优化。Logback 被广泛用于各种 Java 应用程序中, 包括 Web 应用、企业应用和后端服务。以下是 Logback 的主要特点和用法:")]),t._v(" "),s("p",[s("strong",[t._v("特点")]),t._v(":")]),t._v(" "),s("ul",[s("li",[s("p",[t._v("高性能: Logback 被设计为高性能的日志框架, 能够在不影响应用程序性能的情况下记录大量日志。")])]),t._v(" "),s("li",[s("p",[t._v("灵活的配置: Logback 支持 XML 和 Groovy 等多种配置方式, 允许开发人员灵活配置日志记录器、格式化器、输出目标等。")])]),t._v(" "),s("li",[s("p",[t._v("多种输出目标: Logback 支持多种输出目标, 包括控制台、文件、远程服务器、数据库等。您可以根据需要将日志记录到不同的地方。")])]),t._v(" "),s("li",[s("p",[t._v("异步日志记录: Logback 支持异步日志记录, 可以将日志记录操作异步执行, 以提高应用程序的性能。")])]),t._v(" "),s("li",[s("p",[t._v("可插拔的组件: Logback 的组件(如 Appenders、Layouts 和 Filters)都是可插拔的, 可以根据需求进行扩展或替换。")])]),t._v(" "),s("li",[s("p",[t._v("日志级别: Logback 支持不同的日志级别, 包括 TRACE、DEBUG、INFO、WARN 和 ERROR, 允许开发人员根据需要记录不同详细程度的日志。")])])]),t._v(" "),s("p",[s("strong",[t._v("用法")]),t._v(":")]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("添加 Logback 依赖")]),t._v(": 首先, 在项目的依赖管理中添加 Logback 的依赖。通常, 您可以在 Maven 或 Gradle 中添加以下依赖:")])]),t._v(" "),s("div",{staticClass:"language-xml line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("ch.qos.logback"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("groupId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("logback-classic"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("artifactId")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("2.0.0"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("dependency")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br")])]),s("ol",{attrs:{start:"2"}},[s("li",[s("strong",[t._v("创建 Logback 配置文件")]),t._v(": 您需要创建 Logback 的配置文件, 通常命名为"),s("code",[t._v("logback.xml")]),t._v("或"),s("code",[t._v("logback.groovy")]),t._v("。该文件用于配置日志记录器、输出目标、格式化等。")])]),t._v(" "),s("p",[t._v("以下是一个示例的 logback.xml 配置文件:")]),t._v(" "),s("div",{staticClass:"language-xml line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-xml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("configuration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("appender")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("CONSOLE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("ch.qos.logback.core.ConsoleAppender"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("encoder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("pattern")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("pattern")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("encoder")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("appender")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("root")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("level")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("debug"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("appender-ref")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("ref")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("CONSOLE"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("root")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")]),t._v("configuration")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br")])]),s("ol",{attrs:{start:"3"}},[s("li",[s("strong",[t._v("在代码中使用 Logback")]),t._v(": 在应用程序代码中, 您可以通过 Logback 的日志记录器(Logger)来记录日志。通常, 您需要在类中创建一个 Logger 实例, 并使用不同级别的日志记录方法来记录信息。")])]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("slf4j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Logger")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token import"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("org"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("slf4j"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LoggerFactory")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyClass")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Logger")]),t._v(" logger "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LoggerFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getLogger")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyClass")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("doSomething")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("debug")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Debug message"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("info")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Info message"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("warn")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Warning message"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n logger"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("error")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Error message"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br")])]),s("ol",{attrs:{start:"4"}},[s("li",[s("strong",[t._v("运行和查看日志")]),t._v(": 运行应用程序后, Logback 将根据配置记录日志。您可以在控制台、日志文件或其他配置的输出目标中查看日志信息。")])]),t._v(" "),s("p",[t._v("总之, Logback 是一个功能强大且易于使用的日志框架, 它可以帮助您在 Java 应用程序中进行灵活和高性能的日志记录。通过合适的配置和日志级别, 您可以控制日志的详细程度, 并轻松地跟踪和调试应用程序。")]),t._v(" "),s("h2",{attrs:{id:"mybatis"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mybatis"}},[t._v("#")]),t._v(" mybatis")]),t._v(" "),s("p",[s("strong",[t._v("链接:")])]),t._v(" "),s("ul",[s("li",[t._v("Mybatis 官方文档: "),s("a",{attrs:{href:"http://www.mybatis.org/mybatis-3/zh/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("http://www.mybatis.org/mybatis-3/zh/index.html"),s("OutboundLink")],1)]),t._v(" "),s("li",[t._v("Mybatis 官方脚手架文档: "),s("a",{attrs:{href:"http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/",target:"_blank",rel:"noopener noreferrer"}},[t._v("http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/"),s("OutboundLink")],1)]),t._v(" "),s("li",[t._v("Mybatis 整合 Spring Boot 官方 demo: "),s("a",{attrs:{href:"https://github.com/mybatis/spring-boot-starter/tree/master/mybatis-spring-boot-samples",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/mybatis/spring-boot-starter/tree/master/mybatis-spring-boot-samples"),s("OutboundLink")],1)])]),t._v(" "),s("p",[s("strong",[t._v("原理简述:")])]),t._v(" "),s("p",[t._v("MyBatis 是一个流行的 Java 持久性框架, 它提供了一种将 Java 对象映射到数据库表的方法, 同时还支持灵活的 SQL 查询。下面是 MyBatis 的一些核心原理和工作方式:")]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[t._v("SQL 映射文件")])]),t._v(" "),s("p",[t._v("MyBatis 的核心是 SQL 映射文件, 这些文件包含了 SQL 语句和映射规则, 将 Java 对象与数据库表进行映射。每个映射文件通常对应一个数据库表, 并定义了如何将数据从数据库表映射到 Java 对象以及反之。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("配置文件")])]),t._v(" "),s("p",[t._v("MyBatis 需要一个配置文件来初始化和配置框架。该配置文件指定了数据库连接信息、映射文件的位置、缓存策略等配置选项。这个配置文件通常是 mybatis-config.xml。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("SqlSessionFactory")])]),t._v(" "),s("p",[t._v("SqlSessionFactory 是 MyBatis 的核心接口之一, 它是用于创建 SqlSession 的工厂。SqlSession 是 MyBatis 中用于执行 SQL 操作的主要接口。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("SqlSession")])]),t._v(" "),s("p",[t._v("SqlSession 表示与数据库的一次会话, 它提供了执行 SQL 语句、提交事务、关闭会话等操作。通常, 每个数据库操作都需要创建一个 SqlSession 实例。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("Mapper 接口")])]),t._v(" "),s("p",[t._v("MyBatis 支持将 SQL 映射文件中的 SQL 语句绑定到 Java 接口的方法上。开发者可以创建 Mapper 接口, 并使用注解或 XML 配置将接口方法与 SQL 语句进行绑定。MyBatis 会自动生成 Mapper 接口的实现类, 用于执行 SQL 操作。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("执行 SQL 查询")])]),t._v(" "),s("p",[t._v("当应用程序调用 Mapper 接口的方法时, MyBatis 会根据方法的配置找到相应的 SQL 语句, 并将参数传递给 SQL 语句执行。查询结果将被映射到 Java 对象, 并返回给调用方。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("缓存")])]),t._v(" "),s("p",[t._v("MyBatis 支持查询结果的缓存, 以提高性能。它支持两种缓存: 本地缓存(SqlSession 级别)和二级缓存(全局级别)。开发者可以根据需求配置缓存。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("动态 SQL")])]),t._v(" "),s("p",[t._v("MyBatis 允许使用动态 SQL 构建复杂的 SQL 查询。动态 SQL 允许根据条件包含或排除 SQL 语句的一部分, 以实现动态的 SQL 查询。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("事务管理")])]),t._v(" "),s("p",[t._v("MyBatis 支持事务管理, 可以通过配置来启用或禁用事务。开发者可以使用 commit 和 rollback 操作来管理事务。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("插件机制")])]),t._v(" "),s("p",[t._v("MyBatis 提供了一个插件机制, 允许开发者扩展框架的功能。您可以编写自定义插件, 例如自定义拦截器, 来干预 SQL 执行过程。")])])]),t._v(" "),s("p",[t._v("总之, MyBatis 的核心原理涉及 SQL 映射文件、配置文件、SqlSessionFactory、SqlSession、Mapper 接口、SQL 执行、缓存、事务管理等组件的协同工作, 使开发者能够轻松地进行数据库访问并进行对象-关系映射。这使得 MyBatis 成为了一个强大且灵活的持久层框架。")]),t._v(" "),s("h2",{attrs:{id:"nginx"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#nginx"}},[t._v("#")]),t._v(" nginx")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://www.nginx.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("nginx"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://cloud.tencent.com/developer/article/1943958",target:"_blank",rel:"noopener noreferrer"}},[t._v("全面了解 Nginx 主要应用场景"),s("OutboundLink")],1)])]),t._v(" "),s("p",[t._v('Nginx(发音为"engine-x")是一个高性能的开源 Web 服务器, 也可以用作反向代理服务器、负载均衡器、HTTP 缓存以及用于处理 HTTP 请求的应用程序服务器。以下是关于 Nginx 的一些重要信息和功能:')]),t._v(" "),s("ul",[s("li",[s("p",[t._v("高性能: Nginx 以其出色的性能而闻名, 特别适用于高流量的网站和应用程序。它使用异步事件驱动的架构, 能够处理大量并发连接而不消耗太多内存或系统资源。")])]),t._v(" "),s("li",[s("p",[t._v("反向代理: Nginx 可以用作反向代理服务器, 将客户端请求转发给后端服务器, 然后将响应返回给客户端。这使得 Nginx 成为构建可伸缩的应用程序架构的重要工具, 可以将流量分发给多个后端服务器。")])]),t._v(" "),s("li",[s("p",[t._v("负载均衡: Nginx 支持多种负载均衡算法, 包括轮询、IP 哈希、最小连接数等。这使得它可以均衡地分发请求到多个后端服务器, 提高应用程序的可用性和性能。")])]),t._v(" "),s("li",[s("p",[t._v("HTTP 缓存: Nginx 充当 HTTP 缓存代理时, 可以缓存响应数据, 减轻后端服务器的负载, 并加快客户端的响应时间。它支持静态文件缓存以及动态内容的缓存。")])]),t._v(" "),s("li",[s("p",[t._v("SSL/TLS 终止: Nginx 可以终止 SSL/TLS 连接, 允许您在 Nginx 服务器上配置和管理 HTTPS 通信。这对于加密 Web 流量非常重要。")])]),t._v(" "),s("li",[s("p",[t._v("虚拟主机: Nginx 支持虚拟主机配置, 使得可以在同一台服务器上托管多个域名或应用程序, 同时保持隔离性和安全性。")])]),t._v(" "),s("li",[s("p",[t._v("模块化架构: Nginx 的模块化架构允许您根据需要加载不同的功能模块, 因此可以根据特定的用例自定义配置。")])]),t._v(" "),s("li",[s("p",[t._v("日志和监控: Nginx 生成详细的访问日志, 可以帮助您监控网站或应用程序的性能, 并进行故障排除。")])]),t._v(" "),s("li",[s("p",[t._v("开源和社区支持: Nginx 是一个开源项目, 拥有庞大的社区, 提供了丰富的文档、插件和扩展, 以及活跃的讨论和支持。")])])]),t._v(" "),s("p",[t._v("总的来说, Nginx 是一个强大而灵活的 Web 服务器和反向代理服务器, 适用于各种用例, 从简单的静态网站托管到大规模的应用程序负载均衡。它是许多现代 Web 架构的关键组件之一。")]),t._v(" "),s("h2",{attrs:{id:"kibana"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#kibana"}},[t._v("#")]),t._v(" kibana")]),t._v(" "),s("p",[t._v("Kibana 是一个开源的数据可视化工具, 通常与 Elasticsearch 结合使用, 用于实时地探索、分析和可视化存储在 Elasticsearch 中的数据。Kibana 的主要功能包括:")]),t._v(" "),s("ul",[s("li",[s("p",[t._v("数据可视化: Kibana 允许用户创建各种类型的数据可视化, 包括折线图、柱状图、饼图、地图、仪表盘等, 以便更直观地理解数据。")])]),t._v(" "),s("li",[s("p",[t._v("实时搜索和过滤: 用户可以使用 Kibana 的搜索和过滤功能, 轻松地在大量数据中查找、筛选和定位感兴趣的信息。")])]),t._v(" "),s("li",[s("p",[t._v("仪表盘: Kibana 仪表盘是一个可自定义的集合, 可以将多个可视化组件组合到一个页面上, 以创建自己的仪表盘, 以便监控关键性能指标和数据。")])]),t._v(" "),s("li",[s("p",[t._v("日志和事件数据分析: Kibana 被广泛用于分析大规模的日志和事件数据, 帮助运维人员、开发人员和安全团队查找问题、追踪日志、发现异常和实施安全监控。")])]),t._v(" "),s("li",[s("p",[t._v("地理数据可视化: Kibana 具有地图可视化功能, 可以在地图上显示地理位置相关的数据, 如地理热图、点云图、区域边界等。")])]),t._v(" "),s("li",[s("p",[t._v("插件扩展: Kibana 是可扩展的, 可以通过插件和扩展来增强其功能, 满足不同的需求。Elastic 提供了丰富的插件, 同时社区也开发了许多第三方插件。")])]),t._v(" "),s("li",[s("p",[t._v("用户管理和访问控制: Kibana 支持用户认证和授权, 可以配置不同用户和角色的访问权限, 以保护敏感数据和控制用户能够执行的操作。")])]),t._v(" "),s("li",[s("p",[t._v("集成 Elasticsearch: Kibana 最常与 Elasticsearch 集成使用, Elasticsearch 作为数据存储和检索引擎, Kibana 则负责数据可视化和分析。这个组合通常与 Logstash 一起使用, 形成 ELK 堆栈, 用于处理、存储和可视化日志数据。")])])]),t._v(" "),s("p",[t._v("总之, Kibana 是一个功能强大的数据可视化工具, 适用于各种领域, 包括运维监控、应用性能分析、日志分析、安全信息与事件管理(SIEM)等。它可以帮助用户更好地理解和利用其数据, 以做出更明智的决策和行动。")]),t._v(" "),s("h2",{attrs:{id:"kubernetes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#kubernetes"}},[t._v("#")]),t._v(" Kubernetes")]),t._v(" "),s("p",[t._v('Kubernetes(通常缩写为 K8s)是一个开源的容器编排平台, 用于自动化应用程序的部署、扩展和管理。Kubernetes 服务器开发涉及构建和维护 Kubernetes 的核心组件, 以及为 Kubernetes 编写扩展和插件。在 Kubernetes 中, 最小的可部署和调度单位是 "Pod", 它可以包含一个或多个容器。以下是 Kubernetes 服务器开发的主要方面和任务:')]),t._v(" "),s("ol",[s("li",[s("strong",[t._v("核心组件开发")])])]),t._v(" "),s("ul",[s("li",[t._v("API 服务器(kube-apiserver): API 服务器是 Kubernetes 集群的控制平面组件之一, 它提供了 Kubernetes API 的端点。开发人员可以扩展 API 服务器以添加自定义 API 资源或自定义控制器。")]),t._v(" "),s("li",[t._v("控制器管理器(kube-controller-manager): Kubernetes 中的控制器负责保持集群的期望状态。您可以编写自定义控制器来管理自定义资源。")]),t._v(" "),s("li",[t._v("调度器(kube-scheduler): 调度器决定在哪个节点上运行 Pod。定制调度策略可能需要修改或扩展调度器。")])]),t._v(" "),s("p",[s("strong",[t._v("2. 插件和扩展")])]),t._v(" "),s("ul",[s("li",[t._v("CRI 插件: Container Runtime Interface(CRI)插件用于与容器运行时交互, 例如 Docker、containerd 等。开发自定义 CRI 插件以支持其他容器运行时。")]),t._v(" "),s("li",[t._v("CNI 插件: Container Network Interface(CNI)插件用于配置 Pod 之间和 Pod 与外部网络之间的网络连接。您可以开发自定义 CNI 插件以满足特定网络要求。")]),t._v(" "),s("li",[t._v("扩展 API: Kubernetes 允许您自定义 API 资源和控制器, 以满足应用程序特定的需求。这可以通过 Kubernetes 的自定义资源定义(CRD)来实现。")])]),t._v(" "),s("p",[s("strong",[t._v("3. 安全性和认证")])]),t._v(" "),s("ul",[s("li",[t._v("确保 Kubernetes 组件的安全性, 并实施适当的身份验证和授权机制以保护集群。")]),t._v(" "),s("li",[t._v("开发和维护服务账户、角色和角色绑定, 以控制 Pod 对 Kubernetes API 的访问权限。")])]),t._v(" "),s("p",[s("strong",[t._v("4. 版本兼容性")])]),t._v(" "),s("ul",[s("li",[t._v("跟踪 Kubernetes 的发行版本, 并确保自己的扩展和插件与不同版本的 Kubernetes 兼容。")])]),t._v(" "),s("p",[s("strong",[t._v("5. 测试和调试")])]),t._v(" "),s("ul",[s("li",[t._v("编写单元测试、集成测试和端到端测试, 以确保自己的代码在 Kubernetes 集群中正常工作。")]),t._v(" "),s("li",[t._v("开发和使用日志记录和监控工具, 以便追踪和解决问题。")])]),t._v(" "),s("p",[s("strong",[t._v("6. 社区参与")])]),t._v(" "),s("ul",[s("li",[t._v("Kubernetes 是一个开源项目, 具有活跃的社区。参与社区, 与其他开发人员合作解决问题, 讨论新功能和改进, 参加工作组和会议。")])]),t._v(" "),s("p",[s("strong",[t._v("7. 文档和教育")])]),t._v(" "),s("ul",[s("li",[t._v("编写文档和教程, 以帮助其他开发人员了解如何使用和扩展 Kubernetes。")])]),t._v(" "),s("p",[t._v("Kubernetes 服务器开发是一个复杂的任务, 需要深入了解 Kubernetes 的核心原理和架构。此外, Kubernetes 社区提供了大量的文档和资源, 以帮助开发人员入门和深入研究 Kubernetes 开发。")]),t._v(" "),s("p",[s("strong",[t._v("链接")])]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://www.redhat.com/zh/topics/containers/kubernetes-architecture#%E6%A6%82%E8%BF%B0",target:"_blank",rel:"noopener noreferrer"}},[t._v("Kubernetes 架构详解"),s("OutboundLink")],1)])]),t._v(" "),s("h2",{attrs:{id:"openssl"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#openssl"}},[t._v("#")]),t._v(" openssl")]),t._v(" "),s("p",[t._v("OpenSSL 是一个强大的开源密码库, 它提供了一系列的密码学工具和函数, 用于保护通信的安全性。OpenSSL 被广泛用于网络通信、数据加密、数字证书管理以及许多其他领域, 包括安全套接层(SSL)和传输层安全(TLS)协议的实现。")]),t._v(" "),s("p",[t._v("以下是 OpenSSL 的一些主要功能和用途:")]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[t._v("加密和解密")]),t._v(": OpenSSL 提供了各种密码算法, 包括对称密钥加密(如 AES、DES)、非对称密钥加密(如 RSA、DSA)以及哈希函数(如 SHA-256)。这些算法可以用于加密和解密数据, 确保数据在传输和存储过程中的机密性。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("数字证书")]),t._v(": OpenSSL 可用于生成和管理数字证书。数字证书是用于验证通信方身份的重要工具, 常用于 HTTPS、电子邮件签名、虚拟专用网络(VPN)等应用中。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("SSL/TLS 支持")]),t._v(": OpenSSL 实现了安全套接层(SSL)和传输层安全(TLS)协议, 用于安全地传输数据。这是保护网页浏览和网络通信的关键技术。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("SSL/TLS 证书颁发")]),t._v(": OpenSSL 可用于创建自签名证书或生成证书签名请求(CSR), 这些证书通常用于建立安全的 HTTPS 连接。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("命令行工具")]),t._v(": OpenSSL 提供了一系列命令行工具, 用于执行各种密码操作, 如生成密钥、创建数字证书、签名和验证数据等。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("密码学工具库")]),t._v(": OpenSSL 提供了一组密码学函数, 可以集成到各种应用程序中, 用于加密和解密数据、生成随机数、计算哈希值等。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("跨平台支持")]),t._v(": OpenSSL 被广泛支持, 可以在多个操作系统上使用, 包括 Linux、Windows、macOS 和其他 Unix 类系统。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("开源和免费")]),t._v(": OpenSSL 是开源项目, 遵循 OpenSSL 许可证, 可以免费使用和分发。")])])]),t._v(" "),s("p",[t._v("由于 OpenSSL 的强大功能和广泛应用, 它在网络安全、数据隐私和加密通信方面发挥着关键作用, 被许多应用程序和服务所采用。同时, 它也需要谨慎使用, 以确保正确的配置和维护, 以避免潜在的安全漏洞。")]),t._v(" "),s("h2",{attrs:{id:"函数扩容"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#函数扩容"}},[t._v("#")]),t._v(" 函数扩容")]),t._v(" "),s("p",[t._v('"函数扩容"通常指的是在计算机科学和编程领域中的一个术语, 用来描述函数(或方法)的能力增强或功能的扩展。这可以通过以下几种方式实现:')]),t._v(" "),s("ul",[s("li",[s("p",[s("strong",[t._v("添加新功能或功能参数")]),t._v(": 在不改变现有代码的前提下, 可以通过向函数添加额外的参数或功能来扩展函数的能力。这样, 函数可以执行更多的任务或适应不同的用例。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("支持不同的数据类型")]),t._v(": 通过改变函数的输入或输出, 可以使函数能够处理更多种类的数据。这通常包括支持更多的数据类型、数据结构或数据格式。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("改进性能或效率")]),t._v(": 对函数进行扩容还可以包括对其进行性能优化, 使其更快或更节省资源。这可以通过算法优化、并行化、异步处理等方式来实现。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("添加异常处理")]),t._v(": 为函数添加错误处理、边界情况的检查和异常处理功能, 以增加函数的健壮性和可靠性。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("提供更多选项")]),t._v(": 通过添加配置参数、标志或开关, 可以让函数的行为变得更加灵活, 以适应不同的需求和情境。")])]),t._v(" "),s("li",[s("p",[s("strong",[t._v("支持插件或扩展")]),t._v(": 设计函数使其可以轻松地扩展或定制, 允许其他开发人员或模块添加自定义功能或扩展函数的功能。")])])]),t._v(" "),s("p",[t._v("函数扩容的目的是增强函数的灵活性、可维护性和可重用性, 以便更好地满足不断变化的需求。在软件开发中, 扩容函数通常是为了避免修改现有代码, 而是通过扩展现有功能来实现新的需求, 从而减少潜在的错误和不稳定性。")]),t._v(" "),s("h2",{attrs:{id:"cdn"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#cdn"}},[t._v("#")]),t._v(" CDN")]),t._v(" "),s("blockquote",[s("p",[t._v("Content Delivery Network (CDN). "),s("a",{attrs:{href:"https://nextjs.org/docs/app/building-your-application/rendering/server-components#static-rendering-default",target:"_blank",rel:"noopener noreferrer"}},[t._v("link"),s("OutboundLink")],1)])]),t._v(" "),s("h2",{attrs:{id:"kafka"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#kafka"}},[t._v("#")]),t._v(" kafka")]),t._v(" "),s("blockquote",[s("p",[t._v("消息队列")])]),t._v(" "),s("p",[t._v("参考: "),s("a",{attrs:{href:"https://juejin.cn/post/6974913928161656863",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://juejin.cn/post/6974913928161656863"),s("OutboundLink")],1)]),t._v(" "),s("RText",{attrs:{text:"优点"}}),t._v(" "),s("ol",[s("li",[t._v("系统解耦。生产端的服务和消息端的服务在遵守同样的接口约束条件下, 可以独立扩展和修改, 而互不影响。")]),t._v(" "),s("li",[t._v("流量削峰。面对突发大流量, 也即生产端生产速度比消费端的消费速度快的时候, 消费端服务不会因为超负荷的请求而完全崩溃。")]),t._v(" "),s("li",[t._v("可扩展性。因为生产者与消费者已经隔离解耦, 所以一旦想增加生产端或消费端的处理逻辑, 或者服务实例等都变得十分容易。")]),t._v(" "),s("li",[t._v("高吞吐量。以时间复杂度为 "),s("code",[t._v("O(1)")]),t._v(" 的方式提供消息持久化能力, 即使对 TB 级以上数据也能保证常数时间复杂度的访问性能。即使在非常廉价的商用机器上也能做到单机支持每秒 100K 条以上消息的传输。")]),t._v(" "),s("li",[t._v("数据冗余存储。Kafka 支持多副本冗余存储机制, 保障不正常宕机之后数据不丢失。")]),t._v(" "),s("li",[t._v("消息顺序性。Kafka 分布式的单位是 partition, Kafka 保证同一个 partition 中的消息的有序性。一个 topic 多个 partition 时, 则不能保证 Topic 级别的消息有序性。")]),t._v(" "),s("li",[t._v("回溯消费。指的是 Kafka 重新设置消息位移 offset。kafka 支持两种方式回溯。一种是基于消息偏移量回溯, 一种是基于时间点的消息回溯。")])]),t._v(" "),s("h2",{attrs:{id:"vps"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#vps"}},[t._v("#")]),t._v(" VPS")]),t._v(" "),s("blockquote",[s("p",[s("RouterLink",{attrs:{to:"/pages/d4f0c7/"}},[t._v("jump")])],1)])],1)}),[],!1,null,null,null);s.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/136.db91a988.js b/assets/js/136.db91a988.js
new file mode 100644
index 00000000000..2e0ac708ad4
--- /dev/null
+++ b/assets/js/136.db91a988.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[136],{452:function(e,r,t){"use strict";t.r(r);var a=t(4),o=Object(a.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"base"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#base"}},[e._v("#")]),e._v(" base")]),e._v(" "),r("h3",{attrs:{id:"install-vercel"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#install-vercel"}},[e._v("#")]),e._v(" install vercel")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("npm i -g vercel")]),e._v(": install")]),e._v(" "),r("li",[r("code",[e._v("vercel -h")]),e._v(": 帮助")])]),e._v(" "),r("h2",{attrs:{id:"case"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#case"}},[e._v("#")]),e._v(" case")]),e._v(" "),r("h3",{attrs:{id:"vercel-app-playground"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#vercel-app-playground"}},[e._v("#")]),e._v(" "),r("a",{attrs:{href:"https://vercel.com/templates/next.js/app-directory",target:"_blank",rel:"noopener noreferrer"}},[e._v("vercel/app-playground"),r("OutboundLink")],1)]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://vercel.com/jackys-projects-aeb870dd/app-router-playground",target:"_blank",rel:"noopener noreferrer"}},[e._v("体验"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/jacky1234/app-router-playground",target:"_blank",rel:"noopener noreferrer"}},[e._v("source code"),r("OutboundLink")],1)])]),e._v(" "),r("h3",{attrs:{id:"nextjs-dashboard"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#nextjs-dashboard"}},[e._v("#")]),e._v(" nextjs-dashboard")]),e._v(" "),r("blockquote",[r("p",[e._v("详情可见链接: "),r("RouterLink",{attrs:{to:"/pages/d2a447/#nextjs-dashboard"}},[e._v("link")])],1)]),e._v(" "),r("h3",{attrs:{id:"python-hello-world"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#python-hello-world"}},[e._v("#")]),e._v(" python hello world")]),e._v(" "),r("blockquote",[r("p",[e._v("This example shows how to use Python on Vercel with Serverless Functions using the Python Runtime.")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://vercel-python-hello-world-ruby.vercel.app/api",target:"_blank",rel:"noopener noreferrer"}},[e._v("体验"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/jacky1234/vercel-python-hello-world.git",target:"_blank",rel:"noopener noreferrer"}},[e._v("source code"),r("OutboundLink")],1)])]),e._v(" "),r("h2",{attrs:{id:"link"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[e._v("#")]),e._v(" link")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://vercel.com/docs/",target:"_blank",rel:"noopener noreferrer"}},[e._v("docs"),r("OutboundLink")],1),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://vercel.com/docs/functions",target:"_blank",rel:"noopener noreferrer"}},[e._v("functions"),r("OutboundLink")],1)])])]),e._v(" "),r("li",[r("a",{attrs:{href:"https://vercel.com/templates",target:"_blank",rel:"noopener noreferrer"}},[e._v("templates"),r("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/137.f31a522d.js b/assets/js/137.f31a522d.js
new file mode 100644
index 00000000000..c38acf0a9ac
--- /dev/null
+++ b/assets/js/137.f31a522d.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[137],{453:function(e,r,a){"use strict";a.r(r);var s=a(4),v=Object(s.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"什么是-ruby"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#什么是-ruby"}},[e._v("#")]),e._v(" 什么是 ruby")]),e._v(" "),r("p",[e._v("Ruby 是一种动态、面向对象、通用编程语言, 由日本程序员松本行弘(Yukihiro Matsumoto)于 1995 年首次发布。Ruby 设计之初的目标是将编程变得更简单和更有趣, 强调可读性和开发者友好性。以下是 Ruby 编程语言的一些重要特点和特性:")]),e._v(" "),r("ul",[r("li",[r("p",[r("code",[e._v("简洁和易读的语法")]),e._v(': Ruby 的语法被设计得非常简洁和易读。它采用了一种自然语言的方式来表达代码, 这使得 Ruby 代码易于编写和维护。Ruby 的设计哲学之一是"优美的代码"。')])]),e._v(" "),r("li",[r("p",[r("code",[e._v("面向对象编程")]),e._v(": 在 Ruby 中, 一切都是对象。Ruby 是一种纯粹的面向对象编程语言, 支持类、继承、多态等面向对象编程概念。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("开发者友好")]),e._v(": Ruby 的设计目标之一是提高开发者的生产力和乐趣。它注重开发者体验, 提供了丰富的内置库和工具, 使编程任务更容易完成。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("强大的标准库")]),e._v(": Ruby 附带了一个强大的标准库, 包含了大量常用功能的模块和类, 可以加速开发过程。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("动态类型系统")]),e._v(": Ruby 使用动态类型系统, 变量的类型在运行时确定。这使得 Ruby 非常灵活, 但也需要谨慎处理类型相关的错误。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("自动内存管理")]),e._v(": Ruby 具有自动垃圾回收功能, 开发者无需手动管理内存, 降低了内存泄漏的风险。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("开放源代码")]),e._v(": Ruby 是一个开源项目, 拥有庞大的社区支持。Ruby 社区贡献了各种库、框架和工具, 用于不同类型的应用开发, 特别是 Web 开发。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("跨平台")]),e._v(": Ruby 可以运行在多个操作系统上, 包括 Linux、macOS、Windows 等。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("丰富的生态系统")]),e._v(": Ruby 生态系统包括 RubyGems(用于包管理的工具)、Ruby on Rails(流行的 Web 开发框架)、RSpec(测试框架)等。这些工具和框架使 Ruby 成为一种强大的开发平台。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("社区支持")]),e._v(": Ruby 社区非常活跃, 提供了大量教程、文档、博客和论坛, 帮助开发者解决问题和学习 Ruby 编程。")])])]),e._v(" "),r("p",[e._v("Ruby 主要用于 Web 开发、脚本编写、数据分析、游戏开发、自动化任务和系统管理等领域。最著名的 Ruby Web 开发框架之一是 Ruby on Rails, 它在构建 Web 应用程序方面非常流行。")]),e._v(" "),r("p",[e._v("总的来说, Ruby 是一种功能丰富且容易学习的编程语言, 适合开发者快速构建各种类型的应用程序。")]),e._v(" "),r("h2",{attrs:{id:"安装-ruby"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#安装-ruby"}},[e._v("#")]),e._v(" 安装 ruby")]),e._v(" "),r("p",[e._v("方法一: rvm")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("curl -L https://get.rvm.io | bash -s stable")]),e._v(": 安装 RVM")]),e._v(" "),r("li",[r("code",[e._v("source ~/.rvm/scripts/rvm")]),e._v(": 载入 RVM 环境")]),e._v(" "),r("li",[r("code",[e._v("rvm install 2.7.0")]),e._v(": 安装 Ruby。\n"),r("ul",[r("li",[r("code",[e._v("brew install autoconf automake libtool pkg-config openssl libyaml readline libxml2 libxslt libffi")]),e._v(": 安装前, 你可能需要先安装编译依赖")])])]),e._v(" "),r("li",[r("code",[e._v("rvm use --default ruby-2.7.0")]),e._v(": 设置 Ruby 版本")]),e._v(" "),r("li",[e._v("其他\n"),r("ul",[r("li",[r("code",[e._v("rvm list known")]),e._v(": 列出已知的 ruby 版本")]),e._v(" "),r("li",[r("code",[e._v("rvm remove [版本号]")]),e._v(": 卸载已安装的版本(若已经安装过 ruby)")]),e._v(" "),r("li",[r("code",[e._v("rvm -v")]),e._v(": 检查 ruby 是否安装好了")])])])]),e._v(" "),r("p",[e._v("【注】使用 rvm 安装 ruby 遇到 ruby 版本与 openssl 版本冲突, 导致本地编译不过的问题。 尝试使用 brew 安装成功, 方法如下, 也可以点击 "),r("a",{attrs:{href:"https://www.ruby-lang.org/en/documentation/installation/#homebrew",target:"_blank",rel:"noopener noreferrer"}},[e._v("链接查看"),r("OutboundLink")],1)]),e._v(" "),r("p",[e._v("方法二: brew")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("brew search ruby")])]),e._v(" "),r("li",[r("code",[e._v("brew install ruby@2.7")])])]),e._v(" "),r("h2",{attrs:{id:"其他"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[e._v("#")]),e._v(" 其他")]),e._v(" "),r("h3",{attrs:{id:"包管理工具-gem"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#包管理工具-gem"}},[e._v("#")]),e._v(" 包管理工具 gem")]),e._v(" "),r("p",[e._v("gem 命令是 RubyGems 包管理系统的命令行工具, 用于安装、管理和发布 Ruby 编程语言的软件包。RubyGems 允许 Ruby 开发者轻松地共享和安装代码库和依赖项。")]),e._v(" "),r("p",[e._v("以下是一些常见的 gem 命令及其用法:")]),e._v(" "),r("ul",[r("li",[r("code",[e._v("gem install package_name")]),e._v(": 安装 gem 包")]),e._v(" "),r("li",[r("code",[e._v("gem install package_name -v xxx")]),e._v(": 指定版本安装")]),e._v(" "),r("li",[r("code",[e._v("gem uninstall package_name")]),e._v(": 卸载 gem 包")]),e._v(" "),r("li",[r("code",[e._v("gem list")]),e._v(": 列出已安装的 gem 包")]),e._v(" "),r("li",[r("code",[e._v("gem info package_name")]),e._v(": 查看 gem 包的详细信息")]),e._v(" "),r("li",[r("code",[e._v("gem search search_term")]),e._v(": 搜索 gem 包")]),e._v(" "),r("li",[r("code",[e._v("gem update package_name")]),e._v(": 更新 gem 包")]),e._v(" "),r("li",[r("code",[e._v("gem sources -l")]),e._v(": 列出可用的 RubyGems 源")]),e._v(" "),r("li",[r("code",[e._v("gem sources --add/remove source_url")]),e._v(": 添加/删除 RubyGems 源")]),e._v(" "),r("li",[r("code",[e._v("gem build package_name.gemspec")]),e._v(": 创建 gem 包")]),e._v(" "),r("li",[r("code",[e._v("gem push package_name-version.gem")]),e._v(": 发布 gem 包")]),e._v(" "),r("li",[e._v("更换源\n"),r("ul",[r("li",[r("code",[e._v("gem sources -l")]),e._v(": 检测 Ruby 源")]),e._v(" "),r("li",[r("code",[e._v("gem sources --remove https://rubygems.org/")]),e._v(": 移除 ruby 源")]),e._v(" "),r("li",[r("code",[e._v("gem sources --add https://gems.ruby-china.com")]),e._v(": 替换添加国内镜像源 ruby-china 源")]),e._v(" "),r("li",[r("code",[e._v("gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/")])]),e._v(" "),r("li",[r("code",[e._v("gem sources -l")]),e._v(": 再次检查此时的 ruby 源")])])])]),e._v(" "),r("p",[r("strong",[e._v("gem sources")])]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://gems.ruby-china.com",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://gems.ruby-china.com"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://mirrors.tuna.tsinghua.edu.cn/rubygems/",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://mirrors.tuna.tsinghua.edu.cn/rubygems/"),r("OutboundLink")],1),e._v(": 清华大学")])]),e._v(" "),r("p",[e._v("RubyGems 是 Ruby 开发的一个重要工具, 用于管理 Ruby 应用程序的依赖项和扩展库。通过 gem 命令, 开发者可以轻松地查找、安装和更新 RubyGem 包, 以加速 Ruby 开发过程。")]),e._v(" "),r("h3",{attrs:{id:"rvm"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#rvm"}},[e._v("#")]),e._v(" RVM")]),e._v(" "),r("p",[e._v("RVM(Ruby Version Manager)是一个用于管理 Ruby 版本的工具, 特别是在 Linux 和 macOS 等类 Unix 系统上广泛使用。RVM 允许开发者在同一台计算机上安装和切换不同版本的 Ruby, 以便在不同项目中使用不同的 Ruby 版本和 gem 包。")]),e._v(" "),r("p",[e._v("RVM 提供以下主要功能:")]),e._v(" "),r("ul",[r("li",[r("p",[r("code",[e._v("多版本管理")]),e._v(": RVM 允许您在同一计算机上安装多个 Ruby 版本, 这对于测试和开发不同 Ruby 应用程序非常有用。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("Gemsets")]),e._v(": RVM 提供 gemset 功能, 可以创建项目特定的 gem 环境。这意味着您可以在不同项目中使用不同的 gem 版本, 而不会干扰全局 gem 环境。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("易于切换")]),e._v(": 通过 RVM, 您可以轻松地在已安装的 Ruby 版本之间切换, 而不必手动更改环境变量。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("Gem 包管理")]),e._v(": RVM 与 gem 包管理工具集成紧密, 可以轻松地安装、更新和删除 gem 包。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("升级和回滚")]),e._v(": RVM 支持 Ruby 版本的升级和回滚, 让您更轻松地管理 Ruby 版本。")])]),e._v(" "),r("li",[r("p",[r("code",[e._v("自动安装依赖")]),e._v(": RVM 可以自动安装 Ruby 所需的依赖库, 这在一些系统上可以减少设置和安装工作。")])])]),e._v(" "),r("p",[e._v("RVM 的使用可以帮助 Ruby 开发者在不同项目中维护不同版本的 Ruby, 从而更好地管理依赖和确保应用程序的稳定性。请注意, 虽然 RVM 在过去非常流行, 但现在也有其他 Ruby 版本管理工具, 如 rbenv 和 asdf, 也受到了广泛的使用。选择哪个工具取决于您的需求和个人偏好。")]),e._v(" "),r("h3",{attrs:{id:"cocoapods"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#cocoapods"}},[e._v("#")]),e._v(" cocoapods")]),e._v(" "),r("p",[r("a",{attrs:{href:"https://cocoapods.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("CocoaPods"),r("OutboundLink")],1),e._v(" is built with Ruby and is installable with the default Ruby available on macOS. We recommend you use the default ruby.")]),e._v(" "),r("p",[e._v("Using the default Ruby install can require you to use sudo when installing gems. Further installation instructions are in the guides.")]),e._v(" "),r("div",{staticClass:"language-shell line-numbers-mode"},[r("pre",{pre:!0,attrs:{class:"language-shell"}},[r("code",[r("span",{pre:!0,attrs:{class:"token function"}},[e._v("sudo")]),e._v(" gem "),r("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" cocoapods\n"),r("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# 安装制定版本的 cocoapods, -n: Directory where executables are located")]),e._v("\n"),r("span",{pre:!0,attrs:{class:"token function"}},[e._v("sudo")]),e._v(" gem "),r("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" "),r("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-n")]),e._v(" /usr/local/bin cocoapods "),r("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-v")]),e._v(" "),r("span",{pre:!0,attrs:{class:"token number"}},[e._v("1.8")]),e._v(".4\n")])]),e._v(" "),r("div",{staticClass:"line-numbers-wrapper"},[r("span",{staticClass:"line-number"},[e._v("1")]),r("br"),r("span",{staticClass:"line-number"},[e._v("2")]),r("br"),r("span",{staticClass:"line-number"},[e._v("3")]),r("br")])]),r("h2",{attrs:{id:"链接"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[e._v("#")]),e._v(" 链接")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://www.geeksforgeeks.org/ruby-programming-language/",target:"_blank",rel:"noopener noreferrer"}},[e._v("ruby-programming-language"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://gems.ruby-china.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("gems.ruby-china"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://rubygems.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("rubygems"),r("OutboundLink")],1),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://guides.rubygems.org/command-reference/",target:"_blank",rel:"noopener noreferrer"}},[e._v("command-reference"),r("OutboundLink")],1)])])]),e._v(" "),r("li",[r("a",{attrs:{href:"https://cocoapods.org/",target:"_blank",rel:"noopener noreferrer"}},[e._v("CocoaPods"),r("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=v.exports}}]);
\ No newline at end of file
diff --git a/assets/js/138.367e06be.js b/assets/js/138.367e06be.js
new file mode 100644
index 00000000000..54ef447df5a
--- /dev/null
+++ b/assets/js/138.367e06be.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[138],{454:function(s,t,a){"use strict";a.r(t);var r=a(4),n=Object(r.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("div",{staticClass:"custom-block theorem"},[t("p",{staticClass:"title"},[s._v("什么是 RSS")]),t("p",[s._v("RSS 的全称为 Really Simple Syndication(简易信息聚合)是一种用于获取即时更新内容的标准格式。它允许用户订阅自己感兴趣的网站内容, 并通过一个 RSS 阅读器或 RSS 聚合器收集和显示这些内容。RSS 聚合器是一种工具, 能够将多个不同来源的 RSS 订阅汇集在一起, 以便用户可以在一个地方查看多个网站的更新。")]),s._v(" "),t("p",[s._v("一个 RSS 聚合器和网络是一个提供订阅和管理 RSS 源的服务。它通常包括以下功能:")]),s._v(" "),t("ul",[t("li",[s._v("订阅管理: 用户可以添加和删除他们感兴趣的 RSS 源。他们可以根据自己的兴趣和喜好, 定制自己的订阅列表。")]),s._v(" "),t("li",[s._v("更新通知: 一旦用户订阅的网站有新的内容发布, 聚合器会自动检测到, 并向用户发送通知。这可以通过电子邮件、移动应用程序通知或在用户界面上显示未读计数等方式实现。")]),s._v(" "),t("li",[s._v("聚合显示: 聚合器会将多个订阅的网站内容集中在一个界面中显示, 用户可以在一个地方浏览和阅读各个网站的更新。这样, 用户不必逐个访问每个网站来查看新的内容。")]),s._v(" "),t("li",[s._v("分类和标签: 聚合器通常允许用户为订阅的源分配分类和标签, 以便更好地组织和管理订阅列表。")]),s._v(" "),t("li",[s._v("搜索功能: 聚合器可能提供搜索功能, 使用户能够在他们的订阅中查找特定的关键词或主题。")]),s._v(" "),t("li",[s._v("社交分享: 有些聚合器还允许用户将感兴趣的内容分享到社交媒体平台或通过电子邮件发送给其他人。")])]),s._v(" "),t("p",[s._v("通过使用一个 RSS 聚合器和网络, 用户可以更方便地跟踪自己关注的网站和内容更新。它提供了一个集中管理和浏览订阅的平台, 使用户能够更高效地获取所需的信息。")])]),t("h2",{attrs:{id:"base"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#base"}},[s._v("#")]),s._v(" base")]),s._v(" "),t("h3",{attrs:{id:"如何寻找-rss-订阅源"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#如何寻找-rss-订阅源"}},[s._v("#")]),s._v(" 如何寻找 RSS 订阅源")]),s._v(" "),t("h3",{attrs:{id:"如何自己制作-rss-订阅源"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#如何自己制作-rss-订阅源"}},[s._v("#")]),s._v(" 如何自己制作 RSS 订阅源")]),s._v(" "),t("h3",{attrs:{id:"构建-rss-阅读流程"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#构建-rss-阅读流程"}},[s._v("#")]),s._v(" 构建 RSS 阅读流程")]),s._v(" "),t("h2",{attrs:{id:"rsshubradar"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rsshubradar"}},[s._v("#")]),s._v(" RSSHubRadar")]),s._v(" "),t("h3",{attrs:{id:"查询符合条件的a元素"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#查询符合条件的a元素"}},[s._v("#")]),s._v(" 查询符合条件的a元素")]),s._v(" "),t("div",{staticClass:"language-python line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-python"}},[t("code",[s._v("response"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("xpath"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("\"//a[contains(@href, '/feed') or contains(@href, '/rss') or contains(@href, '/atom')]\"")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("\" | //a[contains(@title, 'rss') or contains(@title, 'RSS')]\"")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("\" | //a[contains(concat(' ', normalize-space(@class), ' '), ' rss ')]\"")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("\" | //a[contains(., 'rss') or contains(translate(., 'RSS', 'rss'), 'rss')]\"")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("getall"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br")])]),t("h2",{attrs:{id:"link"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[s._v("#")]),s._v(" link")]),s._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/DIYgod/RSSHub",target:"_blank",rel:"noopener noreferrer"}},[s._v("RSSHub"),t("OutboundLink")],1),s._v(", Everything is RSSible\n"),t("ul",[t("li",[t("a",{attrs:{href:"https://docs.rsshub.app/",target:"_blank",rel:"noopener noreferrer"}},[s._v("doc-en"),t("OutboundLink")],1)]),s._v(" "),t("li",[t("a",{attrs:{href:"https://docs.rsshub.app/zh/",target:"_blank",rel:"noopener noreferrer"}},[s._v("doc-zh"),t("OutboundLink")],1)]),s._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/jacky1234/RSSHub-Radar",target:"_blank",rel:"noopener noreferrer"}},[s._v("RSSHub-Radar"),t("OutboundLink")],1),s._v(": chrome extension, forked project")])])]),s._v(" "),t("li",[t("a",{attrs:{href:"https://sspai.com/post/56391",target:"_blank",rel:"noopener noreferrer"}},[s._v("高效获取信息, 你需要这份 RSS 入门指南-少数派"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/139.270ba412.js b/assets/js/139.270ba412.js
new file mode 100644
index 00000000000..301a6af0c75
--- /dev/null
+++ b/assets/js/139.270ba412.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[139],{456:function(t,e,a){"use strict";a.r(e);var r=a(4),s=Object(r.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"category"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#category"}},[t._v("#")]),t._v(" category")]),t._v(" "),e("h3",{attrs:{id:"属性动画"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#属性动画"}},[t._v("#")]),t._v(" 属性动画")]),t._v(" "),e("h3",{attrs:{id:"帧动画"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#帧动画"}},[t._v("#")]),t._v(" 帧动画")]),t._v(" "),e("blockquote",[e("p",[t._v("帧动画是 Android 中的一种简单动画效果, 通过播放一系列连续的静态图片(帧)来实现动画效果。")])]),t._v(" "),e("h3",{attrs:{id:"ae"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#ae"}},[t._v("#")]),t._v(" AE")]),t._v(" "),e("ul",[e("li",[t._v("AE 动画指的是使用 "),e("code",[t._v("Adobe After Effects")]),t._v(" 软件制作的动画效果, 通常用于电影、广告、动画片等领域。")]),t._v(" "),e("li",[t._v("After Effects 提供了丰富的动画制作工具和特效, 可以制作出高质量、复杂的动画效果。")]),t._v(" "),e("li",[t._v("制作完成的 AE 动画可以导出为视频格式或者其他格式进行使用。")])]),t._v(" "),e("h3",{attrs:{id:"lottie"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#lottie"}},[t._v("#")]),t._v(" lottie")]),t._v(" "),e("blockquote",[e("p",[t._v("Lottie is a mobile library for Web, and iOS that parses Adobe After Effects animations exported as json with Bodymovin and renders them natively on mobile! For the first time, designers can create and ship beautiful animations without an engineer painstakingly recreating it by hand.")])]),t._v(" "),e("h2",{attrs:{id:"link"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[t._v("#")]),t._v(" link")]),t._v(" "),e("ul",[e("li",[t._v("lottie\n"),e("ul",[e("li",[e("a",{attrs:{href:"https://www.cnblogs.com/penghuwan/p/11537965.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Lottie 在手, 动画我有: ios/Android/Web 三端复杂帧动画解决方案 "),e("OutboundLink")],1)])])])])])}),[],!1,null,null,null);e.default=s.exports}}]);
\ No newline at end of file
diff --git a/assets/js/14.fdde4a68.js b/assets/js/14.fdde4a68.js
new file mode 100644
index 00000000000..18bcb4d8064
--- /dev/null
+++ b/assets/js/14.fdde4a68.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[14],{333:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/140.a464d52c.js b/assets/js/140.a464d52c.js
new file mode 100644
index 00000000000..c4d54ca0924
--- /dev/null
+++ b/assets/js/140.a464d52c.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[140],{455:function(t,a,r){"use strict";r.r(a);var s=r(4),v=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"base"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#base"}},[t._v("#")]),t._v(" base")]),t._v(" "),a("h3",{attrs:{id:"category"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#category"}},[t._v("#")]),t._v(" category")]),t._v(" "),a("ul",[a("li",[t._v("可逆加密")]),t._v(" "),a("li",[t._v("对称加密: 加密和解密时使用相同的密钥, 常见的有 DES, 3DES, AES, PBE")]),t._v(" "),a("li",[t._v("非对称加密: RSA, DSA, ECC")]),t._v(" "),a("li",[t._v("不可逆加密: 也叫单向加密, 常见的有 MD5, HMAC")])]),t._v(" "),a("h3",{attrs:{id:"sha-256"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sha-256"}},[t._v("#")]),t._v(" sha-256")]),t._v(" "),a("blockquote",[a("p",[t._v("SHA-256(Secure Hash Algorithm 256-bit)是一种广泛使用的加密哈希函数,它由美国国家安全局(NSA)设计,并作为 SHA-2 系列算法的一部分。它具有以下特点:")])]),t._v(" "),a("ol",[a("li",[t._v("固定长度输出")])]),t._v(" "),a("p",[t._v("输出长度为256位(32字节),无论输入数据的大小或长度如何,SHA-256 总是生成一个256位的散列值(哈希值)。")]),t._v(" "),a("ol",{attrs:{start:"2"}},[a("li",[t._v("抗碰撞性")])]),t._v(" "),a("p",[t._v("SHA-256 的设计使得找到两个不同的输入数据生成相同的哈希值(碰撞)非常困难。虽然不存在完全的碰撞防护(理论上仍可能发生),但找到碰撞的概率极低。因此,SHA-256 通常被认为是抗碰撞的。")]),t._v(" "),a("ol",{attrs:{start:"3"}},[a("li",[t._v("抗篡改")])]),t._v(" "),a("p",[t._v("哈希函数的一个重要性质是不可逆性:给定一个哈希值,几乎不可能反推出生成这个哈希值的原始输入。这意味着即使攻击者知道哈希值,也无法直接推断出原始数据。")]),t._v(" "),a("ol",{attrs:{start:"4"}},[a("li",[t._v("小输入变化会引起大的输出变化")])]),t._v(" "),a("p",[t._v("SHA-256 对输入数据非常敏感,即使对输入数据做微小的改动(如改变一个字母或符号),生成的哈希值也会发生剧烈变化。这种特性称为“雪崩效应”,它确保输入数据的任何微小变化都会导致完全不同的哈希值。")]),t._v(" "),a("ol",{attrs:{start:"5"}},[a("li",[t._v("广泛应用")])]),t._v(" "),a("p",[t._v("SHA-256 是当前许多安全协议中的重要组成部分,广泛用于数字签名、数据完整性验证、证书签名、区块链等应用。\n在区块链领域,特别是在比特币等加密货币中,SHA-256 用于挖矿过程以及生成地址。")]),t._v(" "),a("ol",{attrs:{start:"6"}},[a("li",[t._v("速度和安全性平衡")])]),t._v(" "),a("p",[t._v("相较于较短的哈希算法(如 SHA-1),SHA-256 提供了更高的安全性,但计算速度稍慢。虽然它没有 SHA-3 这样的最新算法安全性高,但在大多数场景中,SHA-256 提供了足够的安全保证。")]),t._v(" "),a("ol",{attrs:{start:"7"}},[a("li",[t._v("安全性")])]),t._v(" "),a("p",[t._v("目前没有已知的有效攻击能打破 SHA-256 的安全性。传统的攻击(如暴力破解)由于 SHA-256 的输出长度较大,所需计算资源庞大,因此目前是不可行的。")]),t._v(" "),a("ol",{attrs:{start:"8"}},[a("li",[t._v("抗预映射攻击")])]),t._v(" "),a("p",[t._v("SHA-256 对抗预映射攻击有很强的抵御能力,这意味着给定一个哈希值,要找到一个匹配的输入是极其困难的。")]),t._v(" "),a("ol",{attrs:{start:"9"}},[a("li",[t._v("无密钥")])]),t._v(" "),a("p",[t._v("与对称加密算法不同,SHA-256 是一种无密钥的哈希函数,它不需要密钥参与运算。")]),t._v(" "),a("RText",{attrs:{text:"总结来说,SHA-256 是一种快速、高效且相对安全的哈希算法,广泛应用于各种需要数据完整性、认证、签名等场景中。"}}),t._v(" "),a("h3",{attrs:{id:"对称加密-vs-非对称的加密"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#对称加密-vs-非对称的加密"}},[t._v("#")]),t._v(" 对称加密 vs 非对称的加密")]),t._v(" "),a("p",[a("a",{attrs:{href:"https://zhuanlan.zhihu.com/p/42516761",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://zhuanlan.zhihu.com/p/42516761"),a("OutboundLink")],1)]),t._v(" "),a("ul",[a("li",[t._v("对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。")])]),t._v(" "),a("h2",{attrs:{id:"link"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[t._v("#")]),t._v(" link")]),t._v(" "),a("ul",[a("li",[a("RouterLink",{attrs:{to:"/pages/249de3/"}},[t._v("请求签名分析")])],1),t._v(" "),a("li",[a("a",{attrs:{href:"https://tool.oschina.net/encrypt",target:"_blank",rel:"noopener noreferrer"}},[t._v("在线加密解密"),a("OutboundLink")],1)])])],1)}),[],!1,null,null,null);a.default=v.exports}}]);
\ No newline at end of file
diff --git a/assets/js/141.1244633c.js b/assets/js/141.1244633c.js
new file mode 100644
index 00000000000..90d3da91691
--- /dev/null
+++ b/assets/js/141.1244633c.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[141],{457:function(e,t,a){"use strict";a.r(t);var v=a(4),_=Object(v.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h2",{attrs:{id:"编码"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#编码"}},[e._v("#")]),e._v(" 编码")]),e._v(" "),t("h3",{attrs:{id:"url-编码"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#url-编码"}},[e._v("#")]),e._v(" URL 编码")]),e._v(" "),t("blockquote",[t("p",[t("code",[e._v("%2F")]),e._v(" 与 "),t("code",[e._v("/")]),e._v(" 的编码关系是怎样的?")])]),e._v(" "),t("p",[t("code",[e._v("%2F")]),e._v(" 和 "),t("code",[e._v("/")]),e._v(" 之间存在编码关系。")]),e._v(" "),t("p",[e._v("URL 编码是一种将特殊字符转换为 URL 安全格式的过程。在 URL 中, 某些字符具有特殊含义, 如 "),t("code",[e._v("/")]),e._v(" 是用于分隔路径的字符。如果一个字符在 URL 中具有特殊含义, 但需要表示该字符本身而不是其特殊含义, 就需要对其进行编码。")]),e._v(" "),t("p",[e._v("在 URL 编码中, 每个字符都可以表示为 "),t("code",[e._v("%")]),e._v(" 加上两个十六进制数字的形式。对于 "),t("code",[e._v("/")]),e._v(" 字符, 其编码是 "),t("code",[e._v("%2F")]),e._v("。")]),e._v(" "),t("p",[e._v("当在 URL 中包含 "),t("code",[e._v("/")]),e._v(" 字符时, 为了避免与路径分隔符混淆, 需要对其进行编码, 即将 "),t("code",[e._v("/")]),e._v(" 转换为 "),t("code",[e._v("%2F")]),e._v("。这样可以确保在 URL 中正确传递和解析这个字符。")]),e._v(" "),t("p",[e._v("例如, 如果要将路径 "),t("code",[e._v("/path/to/file")]),e._v(" 进行 URL 编码, 编码后的结果将是 "),t("code",[e._v("%2Fpath%2Fto%2Ffile")]),e._v("。在这个编码后的 URL 中, "),t("code",[e._v("%2F")]),e._v(" 代表原始的 "),t("code",[e._v("/")]),e._v(" 字符。")]),e._v(" "),t("p",[e._v("总结起来, "),t("code",[e._v("%2F")]),e._v(" 是 "),t("code",[e._v("/")]),e._v(" 字符的 URL 编码表示形式, 用于在 URL 中表示路径分隔符而不引起歧义。")]),e._v(" "),t("hr"),e._v(" "),t("RText",{attrs:{text:"常用 URL 编码"}}),e._v(" "),t("p",[e._v("URL 编码是一种将特殊字符转换为 URL 安全格式的方法, 通常使用百分号(%)后跟两个十六进制数字表示字符。以下是一些常见的 URL 编码:")]),e._v(" "),t("ul",[t("li",[e._v('空格: 空格通常被编码为"%20"。')]),e._v(" "),t("li",[e._v('问号(?): 问号通常被编码为"%3F"。')]),e._v(" "),t("li",[e._v('等号(=): 等号通常被编码为"%3D"。')]),e._v(" "),t("li",[e._v('与号(&): 与号通常被编码为"%26"。')]),e._v(" "),t("li",[e._v('斜杠(/): 斜杠通常被编码为"%2F"。')]),e._v(" "),t("li",[e._v('冒号(😃: 冒号通常被编码为"%3A"。')]),e._v(" "),t("li",[e._v('井号(#): 井号通常被编码为"%23"。')]),e._v(" "),t("li",[e._v('百分号(%): 百分号自身也需要进行编码, 变成"%25"。')]),e._v(" "),t("li",[e._v('加号(+): 在 URL 查询字符串中, 加号通常用来表示空格, 所以它有时需要编码为"%2B"。')]),e._v(" "),t("li",[e._v("其他特殊字符: 根据需要, 其他特殊字符也可以被编码, 例如: 空格(%20)、双引号(%22)、单引号(%27)、大于号(%3E)、小于号(%3C)等。")])]),e._v(" "),t("p",[e._v("请注意, 不同编程语言和库提供了用于 URL 编码和解码的内置函数或方法, 以便更容易地处理 URL 中的特殊字符。")]),e._v(" "),t("h3",{attrs:{id:"ascii"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ascii"}},[e._v("#")]),e._v(" ASCII")]),e._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://tool.oschina.net/commons?type=4",target:"_blank",rel:"noopener noreferrer"}},[e._v("常用对照表"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("ASCII(American Standard Code for Information Interchange)字符集是一个最初为英语和其他西欧语言设计的字符编码标准。它使用 7 位(或 8 位, 包括一个奇偶校验位)来表示字符, 包括控制字符、数字、字母、标点符号和特殊字符。ASCII 字符集包括以下内容:")]),e._v(" "),t("ul",[t("li",[t("strong",[e._v("控制字符")]),e._v(": 这些字符通常没有可见的图形表示, 用于控制文本终端和通信设备的行为。例如, 换行符(\\n)、回车符(\\r)和制表符(\\t)等。")]),e._v(" "),t("li",[t("strong",[e._v("可打印字符")]),e._v(": 这些字符具有可见的图形表示, 包括大写字母(A-Z)、小写字母(a-z)、数字(0-9)和常见标点符号(例如逗号、句点、感叹号等)。")]),e._v(" "),t("li",[t("strong",[e._v("特殊字符")]),e._v(": 这些字符包括空格(空格符)、制表符(\\t)、换行符(\\n)、回车符(\\r)以及其他一些特殊用途的字符(例如退格符 \\b)。")])]),e._v(" "),t("p",[e._v("ASCII 字符集总共包含 128 个字符, 编号从 0 到 127。这些字符在计算机和通信中被广泛使用, 尤其是在早期计算机系统和文本通信中。由于它是一个 7 位字符集, 因此只包含 128 个字符, 不包括一些非拉丁字符(例如希腊字母、俄罗斯字母等)。")]),e._v(" "),t("p",[e._v("虽然 ASCII 字符集最初是为英语设计的, 但它仍然是计算机系统中最常见的字符编码之一, 并且在许多编程语言、操作系统和通信协议中被广泛使用。然而, 在处理多语言文本和国际化需求时, 通常需要使用更多容纳更多字符的字符编码, 例如 UTF-8、UTF-16 等")]),e._v(" "),t("h3",{attrs:{id:"base64"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#base64"}},[e._v("#")]),e._v(" base64")]),e._v(" "),t("blockquote",[t("p",[e._v("Base64(基底64)是一种基于64个可打印字符来表示二进制数据的表示方法. "),t("a",{attrs:{href:"https://zh.wikipedia.org/wiki/Base64",target:"_blank",rel:"noopener noreferrer"}},[e._v("wiki"),t("OutboundLink")],1)])]),e._v(" "),t("h3",{attrs:{id:"unicode"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#unicode"}},[e._v("#")]),e._v(" unicode")]),e._v(" "),t("p",[e._v("现代的操作系统、浏览器、文本编辑器和大多数现代应用程序都支持 Unicode,并且能够渲染 Unicode 字符。Unicode 是一个国际标准,用于一致地编码和表示文本。它包括了几乎所有的文字字符和许多符号,包括表情符号。")]),e._v(" "),t("p",[e._v("当你在文本中插入一个 Unicode 表情字符时,支持 Unicode 的系统会识别并渲染它为相应的表情符号。下面是一些具体原因:")]),e._v(" "),t("ul",[t("li",[e._v("Unicode 支持: 操作系统和应用程序支持 Unicode,能够识别并显示 Unicode 字符。")]),e._v(" "),t("li",[e._v("字体支持: 系统字体包含了这些 Unicode 表情符号,并且知道如何渲染它们。")]),e._v(" "),t("li",[e._v("编码识别: 文本编辑器和浏览器会识别文本编码,并正确渲染 Unicode 字符。")])]),e._v(" "),t("p",[e._v("在代码中的使用你也可以在代码中直接使用这些 Unicode 表情符号。例如,在 JavaScript 中:")]),e._v(" "),t("div",{staticClass:"language-javascript line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-javascript"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("const")]),e._v(" message "),t("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Hello, world! 😊"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\nconsole"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("log")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("message"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])]),e._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[e._v("1")]),t("br"),t("span",{staticClass:"line-number"},[e._v("2")]),t("br")])]),t("p",[e._v("这样做会在控制台中输出带有表情符号的消息。")]),e._v(" "),t("h2",{attrs:{id:"字节码处理"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#字节码处理"}},[e._v("#")]),e._v(" 字节码处理")]),e._v(" "),t("h3",{attrs:{id:"big-little-endian"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#big-little-endian"}},[e._v("#")]),e._v(" big/little endian")]),e._v(" "),t("blockquote",[t("p",[e._v("大端(big endian)和小端(little endian). "),t("a",{attrs:{href:"https://zhuanlan.zhihu.com/p/77436031",target:"_blank",rel:"noopener noreferrer"}},[e._v("link"),t("OutboundLink")],1),e._v(". hexdump 输出 16 进制 "),t("RouterLink",{attrs:{to:"/pages/0140a0/#hexdump"}},[e._v("jump")])],1)]),e._v(" "),t("p",[e._v("字节存储顺序主要分为大端序(Big-endian)和小端序(Little-endian),区别如下")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("Big-endian")]),e._v(": 高位字节存入低地址,低位字节存入高地址")]),e._v(" "),t("li",[t("code",[e._v("Little-endian")]),e._v(": 低位字节存入低地址,高位字节存入高地址。 (低字节在前,高字节在后)")])]),e._v(" "),t("p",[e._v("一般来说,x86 系列 CPU 都是 Little-endian 字节序,PowerPC 通常是 Big-endian 字节序。")]),e._v(" "),t("p",[e._v("因为网络协议也都是采用 Big-endian 方式传输数据的,所以有时也把 Big-endian 方式称为网络字节序.")]),e._v(" "),t("h2",{attrs:{id:"link"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[e._v("#")]),e._v(" link")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://tool.oschina.net/encode",target:"_blank",rel:"noopener noreferrer"}},[e._v("编码在线编码转换"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"http://www.esjson.com/unicodeEncode.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("编码转换"),t("OutboundLink")],1)])])],1)}),[],!1,null,null,null);t.default=_.exports}}]);
\ No newline at end of file
diff --git a/assets/js/142.56628bcb.js b/assets/js/142.56628bcb.js
new file mode 100644
index 00000000000..f8acb26b0f9
--- /dev/null
+++ b/assets/js/142.56628bcb.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[142],{458:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("blockquote",[t("p",[s._v("介绍配置文件的格式。 常见的有 json、yml、toml、ini 等配置")])]),s._v(" "),t("h2",{attrs:{id:"toml"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#toml"}},[s._v("#")]),s._v(" toml")]),s._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://toml.io/en/",target:"_blank",rel:"noopener noreferrer"}},[s._v("Tom's Obvious Minimal Language"),t("OutboundLink")],1),s._v(". A config file format for humans. 支持更多的数据类型,包括字符串、整数、浮点数、布尔值、日期时间等")])]),s._v(" "),t("div",{staticClass:"language-yml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-yml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 服务器配置")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("server"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v('\nname = "example'),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v('server"\nip = "192.168.1.1"\nenabled = true\nport = 8080\n\n'),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 数据库配置")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("database"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v('\nserver = "localhost"\nport = 3306\nusername = "user"\npassword = "password"\ntimeout = 30.5\nmax_connections = 100\n\n'),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 日志配置")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("log"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v('\nlevel = "debug"\nfile = "/var/log/app.log"\n\n'),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 嵌套表格(nested tables)")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("owner"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v('\nname = "Tom Preston'),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v('Werner"\ndob = 1979'),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("05"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("-")]),s._v("27T07"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("32"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v("00Z "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 日期时间类型")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("database.replication"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v('\nenabled = true\nmode = "async"\nservers = '),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"192.168.1.2"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"192.168.1.3"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# array")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("album.tracks"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v('\ntitle = "Overture of Efficiency"\nduration = "4'),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v('30"\n\n'),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("album.tracks"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v('\ntitle = "Ballad of Simplicity"\nduration = "5'),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v('20"\n')])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br"),t("span",{staticClass:"line-number"},[s._v("39")]),t("br")])]),t("h3",{attrs:{id:"定义list"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#定义list"}},[s._v("#")]),s._v(" 定义list")]),s._v(" "),t("ol",[t("li",[s._v("简单值的列表")])]),s._v(" "),t("p",[s._v("如果你想定义一个包含简单值(如字符串、数字、布尔值等)的列表,可以像下面这样定义:")]),s._v(" "),t("div",{staticClass:"language-toml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-toml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("names")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Alice"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Bob"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Charlie"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("ages")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("25")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("30")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("35")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("is_active")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br")])]),t("ol",{attrs:{start:"2"}},[t("li",[s._v("对象(表)的列表")])]),s._v(" "),t("p",[s._v("TOML 支持定义一组对象(也称为表)的列表,每个对象可以拥有自己的字段。")]),s._v(" "),t("p",[s._v("方法一:使用表数组 ("),t("code",[s._v("[[array_name]]")]),s._v("), "),t("a",{attrs:{href:"https://toml.io/en/v1.0.0#table",target:"_blank",rel:"noopener noreferrer"}},[s._v("link"),t("OutboundLink")],1)]),s._v(" "),t("p",[s._v("表数组是 TOML 的一种语法,用于定义包含对象的列表。在这种语法中,每个对象用 "),t("code",[s._v("[[array_name]]")]),s._v(" 来定义。")]),s._v(" "),t("div",{staticClass:"language-toml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-toml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token table class-name"}},[s._v("users")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("name")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Alice"')]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("age")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("25")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token table class-name"}},[s._v("users")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("name")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Bob"')]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("age")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("30")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token table class-name"}},[s._v("users")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("name")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Charlie"')]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("age")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("35")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br")])]),t("p",[s._v("这表示 users 是一个表数组,包含 3 个对象,每个对象都有 name 和 age 字段。")]),s._v(" "),t("p",[s._v("方法二:对象列表的简写(嵌套对象的数组)")]),s._v(" "),t("p",[s._v("如果你需要将对象的定义放在一个数组中,可以直接嵌套对象作为数组的元素。这种方式更简洁,但适合数据量较少且结构较简单的情况。")]),s._v(" "),t("div",{staticClass:"language-toml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-toml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("users")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("name")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Alice"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("age")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("25")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("name")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Bob"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("age")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("30")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("name")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Charlie"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("age")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("35")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br")])]),t("p",[s._v("这与方法一的功能相同,但在 TOML 中更加紧凑。")]),s._v(" "),t("ol",{attrs:{start:"3"}},[t("li",[s._v("嵌套列表")])]),s._v(" "),t("p",[s._v("TOML 还允许定义嵌套的列表,例如一个列表中的每个元素又是一个列表:")]),s._v(" "),t("div",{staticClass:"language-toml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-toml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("matrix")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("3")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("4")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("5")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("6")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("7")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("8")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("9")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br")])]),t("p",[s._v("总结")]),s._v(" "),t("ul",[t("li",[s._v("简单值列表使用方括号 []。")]),s._v(" "),t("li",[s._v("对象列表可以使用 [[array_name]] 或嵌套对象数组的形式 {}。")])]),s._v(" "),t("p",[s._v("根据你的数据结构选择最合适的方式来定义 TOML 列表对象。")]),s._v(" "),t("h2",{attrs:{id:"yaml"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#yaml"}},[s._v("#")]),s._v(" yaml")]),s._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://yaml.org/",target:"_blank",rel:"noopener noreferrer"}},[s._v("link"),t("OutboundLink")],1)])]),s._v(" "),t("h2",{attrs:{id:"ini"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ini"}},[s._v("#")]),s._v(" ini")]),s._v(" "),t("h2",{attrs:{id:"faq"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#faq"}},[s._v("#")]),s._v(" faq")]),s._v(" "),t("h3",{attrs:{id:"toml-vs-ini"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#toml-vs-ini"}},[s._v("#")]),s._v(" toml vs ini")]),s._v(" "),t("p",[s._v("TOML(Tom's Obvious, Minimal Language)和 INI 文件确实有一些相似之处,但它们也有一些显著的不同点。让我们看看它们的相似和不同之处。")]),s._v(" "),t("RText",{attrs:{text:"相似之处:"}}),s._v(" "),t("ul",[t("li",[s._v("节的定义: 两者都使用方括号 "),t("code",[s._v("[]")]),s._v(" 来定义节。")]),s._v(" "),t("li",[s._v("键值对: 两者都使用键值对的形式来配置参数。")])]),s._v(" "),t("RText",{attrs:{text:"不同之处:"}}),s._v(" "),t("ul",[t("li",[s._v("数据类型:"),t("code",[s._v("TOML")]),s._v(" 支持更多的数据类型,包括字符串、整数、浮点数、布尔值、日期时间等。而 INI 文件的值通常被视为字符串。")]),s._v(" "),t("li",[s._v("数组和表: "),t("code",[s._v("TOML")]),s._v(" 支持数组和嵌套表(表是键值对的集合),而 INI 文件通常不直接支持这些复杂的数据结构。")]),s._v(" "),t("li",[s._v("语法细节: "),t("code",[s._v("TOML")]),s._v(" 在语法上更严格,支持更复杂的嵌套结构和数据类型,而 INI 更为简单和宽松。")])]),s._v(" "),t("p",[s._v("以下是您的示例配置文件的 "),t("code",[s._v("TOML")]),s._v(" 和 "),t("code",[s._v("INI")]),s._v(" 格式的比较:")]),s._v(" "),t("RText",{attrs:{text:"TOML 配置文件"}}),s._v(" "),t("div",{staticClass:"language-toml line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-toml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token table class-name"}},[s._v("database")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("server")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"localhost"')]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("port")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("3306")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("username")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"user"')]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("password")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"password"')]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br")])]),t("RText",{attrs:{text:"INI 配置文件"}}),s._v(" "),t("div",{staticClass:"language-ini line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-ini"}},[t("code",[t("span",{pre:!0,attrs:{class:"token section"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token section-name selector"}},[s._v("database")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")])]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key attr-name"}},[s._v("server")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token value attr-value"}},[s._v("localhost")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key attr-name"}},[s._v("port")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token value attr-value"}},[s._v("3306")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key attr-name"}},[s._v("username")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token value attr-value"}},[s._v("user")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key attr-name"}},[s._v("password")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token value attr-value"}},[s._v("password")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br")])]),t("h2",{attrs:{id:"link"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[s._v("#")]),s._v(" link")]),s._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://tennen.medium.com/xml-json-toml-yaml-which-one-is-the-secret-key-to-your-data-success-bc2895d609ae",target:"_blank",rel:"noopener noreferrer"}},[s._v("XML, JSON, TOML, YAML: Which One is the Secret Key to Your Data Success?"),t("OutboundLink")],1)])])],1)}),[],!1,null,null,null);t.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/143.580d9658.js b/assets/js/143.580d9658.js
new file mode 100644
index 00000000000..e27854cbaaf
--- /dev/null
+++ b/assets/js/143.580d9658.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[143],{459:function(s,a,t){"use strict";t.r(a);var e=t(4),n=Object(e.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h2",{attrs:{id:"base"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#base"}},[s._v("#")]),s._v(" base")]),s._v(" "),a("ul",[a("li",[a("code",[s._v(".")]),s._v(": 除换行符以外的所有字符。")]),s._v(" "),a("li",[a("code",[s._v("^")]),s._v(": 字符串开头。")]),s._v(" "),a("li",[a("code",[s._v("$")]),s._v(": 字符串结尾。")]),s._v(" "),a("li",[a("code",[s._v("\\d,\\w,\\s")]),s._v(": 匹配数字、字符、空格。")]),s._v(" "),a("li",[a("code",[s._v("\\D,\\W,\\S")]),s._v(": 匹配非数字、非字符、非空格。")]),s._v(" "),a("li",[a("code",[s._v("[abc]")]),s._v(": 匹配 a、b 或 c 中的一个字母。")]),s._v(" "),a("li",[a("code",[s._v("[a-z]")]),s._v(": 匹配 a 到 z 中的一个字母。")]),s._v(" "),a("li",[a("code",[s._v("[^abc]")]),s._v(": 匹配除了 a、b 或 c 中的其他字母。")]),s._v(" "),a("li",[a("code",[s._v("aa|bb")]),s._v(": 匹配 aa 或 bb。")]),s._v(" "),a("li",[a("code",[s._v("?")]),s._v(": 0 次或 1 次匹配。")]),s._v(" "),a("li",[a("code",[s._v("*")]),s._v(": 匹配 0 次或多次。")]),s._v(" "),a("li",[a("code",[s._v("+")]),s._v(": 匹配 1 次或多次。")]),s._v(" "),a("li",[a("code",[s._v("{n}")]),s._v(": 匹配 n 次。")]),s._v(" "),a("li",[a("code",[s._v("{n,}")]),s._v(": 匹配 n 次以上。")]),s._v(" "),a("li",[a("code",[s._v("{m,n}")]),s._v(": 最少 m 次, 最多 n 次匹配。")]),s._v(" "),a("li",[a("code",[s._v("(expr)")]),s._v(": 捕获 expr 子模式,以 \\1 使用它。")]),s._v(" "),a("li",[a("code",[s._v("(?:expr)")]),s._v(": 忽略捕获的子模式。")]),s._v(" "),a("li",[a("code",[s._v("(?=expr)")]),s._v(": 正向预查模式 expr。")]),s._v(" "),a("li",[a("code",[s._v("(?!expr)")]),s._v(": 负向预查模式 expr")]),s._v(" "),a("li",[a("code",[s._v("[\\u4e00-\\u9fa5]")]),s._v(": 匹配中文")])]),s._v(" "),a("h3",{attrs:{id:"case"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#case"}},[s._v("#")]),s._v(" case")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("runoo+b")]),s._v(", 可以匹配 runoob、runooob、runoooooob 等, + 号代表前面的字符必须至少出现一次(1 次或多次)尝试一下 »。")]),s._v(" "),a("li",[a("code",[s._v("runoo*b")]),s._v(", 可以匹配 runob、runoob、runoooooob 等, * 号代表前面的字符可以不出现, 也可以出现一次或者多次(0 次、或 1 次、或多次)尝试一下 »。")]),s._v(" "),a("li",[a("code",[s._v("colou?r")]),s._v(" 可以匹配 color 或者 colour, ? 问号代表前面的字符最多只可以出现一次(0 次或 1 次)尝试一下 »。")]),s._v(" "),a("li",[a("code",[s._v("colorChangeConfig(?!=undefined)")]),s._v(": 包含colorChangeConfig, 不包含"),a("code",[s._v("=undefined")])])]),s._v(" "),a("h4",{attrs:{id:"负向前瞻断言"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#负向前瞻断言"}},[s._v("#")]),s._v(" 负向前瞻断言")]),s._v(" "),a("p",[a("code",[s._v("/((?!api|_next/static|_next/image|.*\\.png$).*)")])]),s._v(" "),a("ul",[a("li",[a("code",[s._v("((?!...).*)")]),s._v(": 这是一个负向前瞻断言, 它表示后面的表达式不应该匹配某些模式。")]),s._v(" "),a("li",[a("code",[s._v("?!api|_next/static|_next/image|.*\\.png$")]),s._v(": 这是一个子表达式, 包含了要排除的模式列表。\n"),a("ul",[a("li",[a("code",[s._v("api")]),s._v(": 排除了路径中包含 api 的情况。")]),s._v(" "),a("li",[a("code",[s._v("_next/static")]),s._v(": 排除了路径中包含 _next/static 的情况。")]),s._v(" "),a("li",[a("code",[s._v("_next/image")]),s._v(": 排除了路径中包含 _next/image 的情况。")]),s._v(" "),a("li",[a("code",[s._v(".*\\.png$")]),s._v(": 排除了路径以 .png 结尾的情况。")])])])]),s._v(" "),a("p",[s._v("因此, 这个正则表达式的含义是: 匹配所有不包含 "),a("code",[s._v("api、_next/static、_next/image")]),s._v(" 和以 "),a("code",[s._v(".png")]),s._v(" 结尾的路径。换句话说, 中间件将会在这些路径之外的所有路径上执行。")]),s._v(" "),a("h2",{attrs:{id:"复合"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#复合"}},[s._v("#")]),s._v(" 复合")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("^\\d\\.\\s[^\\x00-\\x7F]+: $")]),s._v(": 单数字开头, 随后是一个点号。 后面是空格, 随后是若干个非 ASCII 字符, 最后是一个冒号。")]),s._v(" "),a("li",[a("code",[s._v("(^[^\\x00-\\x7F]+) ([a-zA-Z]) ([^\\x00-\\x7F]):")]),s._v(": 匹配类似 '按下 i 键: '")]),s._v(" "),a("li",[a("code",[s._v("([a-zA-Z.]+)")]),s._v(": 匹配连续的字母和.")]),s._v(" "),a("li",[a("code",[s._v("(^\\w.*):")]),s._v(": 字符开始, 到:")]),s._v(" "),a("li",[a("code",[s._v("(^[^\\s]+):")]),s._v(": 非空格连续")]),s._v(" "),a("li",[a("code",[s._v("^\\d\\. (.*?):")]),s._v(": 如果一行中带多个"),a("code",[s._v(":")]),s._v(",只想匹配到第一个: 截止, ("),a("code",[s._v("2. aaa: bbb:")]),s._v(")")])]),s._v(" "),a("h2",{attrs:{id:"other"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#other"}},[s._v("#")]),s._v(" other")]),s._v(" "),a("h3",{attrs:{id:"捕获分组和非捕获分组的区别"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#捕获分组和非捕获分组的区别"}},[s._v("#")]),s._v(" 捕获分组和非捕获分组的区别")]),s._v(" "),a("p",[s._v("理解非捕获分组的关键在于了解正则表达式中捕获分组和非捕获分组的区别。")]),s._v(" "),a("RText",{attrs:{text:"捕获分组和非捕获分组的区别"}}),s._v(" "),a("ul",[a("li",[s._v("捕获分组: 用圆括号 "),a("code",[s._v("()")]),s._v(" 包围的部分,匹配的内容会被捕获,可以通过反向引用或者程序来提取这些匹配的内容。")]),s._v(" "),a("li",[s._v("非捕获分组: 用 "),a("code",[s._v("(?:...)")]),s._v(" 包围的部分,匹配的内容不会被捕获,不会影响分组的编号,也不能通过反向引用来提取内容。")])]),s._v(" "),a("RText",{attrs:{text:"举个例子"}}),s._v(" "),a("p",[s._v("假设我们有以下字符串和正则表达式:")]),s._v(" "),a("div",{staticClass:"language-text line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[s._v('字符串: "JsApiTransformWork and JsApiTransformTask"\n正则表达式: (\\w+)(Work|Task)\n')])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br")])]),a("p",[s._v("这个正则表达式中包含两个捕获分组:")]),s._v(" "),a("ul",[a("li",[a("code",[s._v("(\\w+)")]),s._v(" 捕获字母或数字的连续字符串。")]),s._v(" "),a("li",[a("code",[s._v("(Work|Task)")]),s._v(" 捕获 Work 或 Task。")])]),s._v(" "),a("p",[s._v("如果你在代码中使用这个正则表达式来匹配字符串,例如在 JavaScript 中:")]),s._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("const")]),s._v(" regex "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token regex"}},[a("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[s._v("/")]),a("span",{pre:!0,attrs:{class:"token regex-source language-regex"}},[s._v("(\\w+)(Work|Task)")]),a("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[s._v("/")]),a("span",{pre:!0,attrs:{class:"token regex-flags"}},[s._v("g")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("const")]),s._v(" str "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JsApiTransformWork and JsApiTransformTask"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("const")]),s._v(" matches "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("...")]),s._v("str"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("matchAll")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("regex"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\nconsole"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("log")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("matches"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br")])]),a("p",[s._v("结果会是这样的:")]),s._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JsApiTransformWork"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JsApiTransform"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Work"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JsApiTransformTask"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JsApiTransform"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Task"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br")])]),a("p",[s._v("这里 matches 包含两个匹配结果,每个匹配结果包含三个部分:")]),s._v(" "),a("p",[s._v('整个匹配的字符串,如 "JsApiTransformWork".\n第一个捕获分组的内容,如 "JsApiTransform".\n第二个捕获分组的内容,如 "Work" 或 "Task".')]),s._v(" "),a("RText",{attrs:{text:"使用非捕获分组"}}),s._v(" "),a("p",[s._v("如果你使用非捕获分组 "),a("code",[s._v("(?:Work|Task)")]),s._v(",正则表达式如下:")]),s._v(" "),a("div",{staticClass:"language-text line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[s._v("(\\w+)(?:Work|Task)\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("再次运行上面的代码,结果会变成这样:")]),s._v(" "),a("div",{staticClass:"language-javascript line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-javascript"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JsApiTransformWork"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JsApiTransform"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JsApiTransformTask"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"JsApiTransform"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br")])]),a("p",[s._v("这里 "),a("code",[s._v("matches")]),s._v(" 仍然包含两个匹配结果,但每个匹配结果只有两个部分:")]),s._v(" "),a("ul",[a("li",[s._v('整个匹配的字符串,如 "JsApiTransformWork".')]),s._v(" "),a("li",[s._v('第一个捕获分组的内容,如 "JsApiTransform".')])]),s._v(" "),a("p",[s._v("这次 Work 或 Task 的匹配结果没有被捕获,也没有出现在 matches 数组中。")]),s._v(" "),a("RText",{attrs:{text:"总结"}}),s._v(" "),a("p",[s._v("使用 "),a("code",[s._v("(?:Work|Task)")]),s._v(" 非捕获分组,意味着我们只想匹配 Work 或 Task,但不需要在匹配结果中提取或引用它们。这样可以简化结果,并且有助于避免不必要的捕获分组。")]),s._v(" "),a("h3",{attrs:{id:"引用捕获组索引"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#引用捕获组索引"}},[s._v("#")]),s._v(" 引用捕获组索引")]),s._v(" "),a("blockquote",[a("p",[s._v("了解 $1")])]),s._v(" "),a("p",[s._v("正则表达式中的 "),a("code",[s._v("$1")]),s._v(" 不是用于匹配文本的模式, 而是用于在正则表达式替换中引用匹配组(捕获组)的特殊语法。它通常用于替换操作, 以便在替换文本中使用匹配的内容。")]),s._v(" "),a("p",[s._v("在正则表达式替换中, 通常使用圆括号 "),a("code",[s._v("()")]),s._v(" 来创建捕获组, 然后可以使用 "),a("code",[s._v("$1")]),s._v("、"),a("code",[s._v("$2")]),s._v("、"),a("code",[s._v("$3")]),s._v(" 等来引用这些捕获组, 以在替换文本中插入匹配的内容。每个 "),a("code",[s._v("$n")]),s._v(" 表示引用第 n 个捕获组的内容。")]),s._v(" "),a("p",[s._v("例如, 假设我们有以下文本:")]),s._v(" "),a("div",{staticClass:"language-yaml line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-yaml"}},[a("code",[a("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("Name")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" John"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("Age")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("30")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("如果我们想要提取名字和年龄, 并在替换文本中使用它们, 可以使用正则表达式:")]),s._v(" "),a("div",{staticClass:"language-yaml line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-yaml"}},[a("code",[a("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("Name")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" (\\w+)"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token key atrule"}},[s._v("Age")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(":")]),s._v(" (\\d+)\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("在替换文本中, 我们可以使用 "),a("code",[s._v("$1")]),s._v(" 来引用第一个捕获组(名字), 使用 "),a("code",[s._v("$2")]),s._v(" 来引用第二个捕获组(年龄)。例如, 可以将其替换为:")]),s._v(" "),a("div",{staticClass:"language-bash line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[s._v("Hello, "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$1")]),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!")]),s._v(" You are "),a("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$2")]),s._v(" years old.\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("替换后的文本将是:")]),s._v(" "),a("div",{staticClass:"language-sql line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-sql"}},[a("code",[s._v("Hello"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" John"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!")]),s._v(" You are "),a("span",{pre:!0,attrs:{class:"token number"}},[s._v("30")]),s._v(" years old"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br")])]),a("p",[s._v("请注意, "),a("code",[s._v("$1")]),s._v(" 在正则表达式模式中不是一个有效的匹配, 而是在替换操作中用于引用捕获组的方式。")]),s._v(" "),a("h2",{attrs:{id:"link"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[s._v("#")]),s._v(" link")]),s._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://www.runoob.com/regexp/regexp-tutorial.html",target:"_blank",rel:"noopener noreferrer"}},[s._v("regex tutorial"),a("OutboundLink")],1)]),s._v(" "),a("li",[a("a",{attrs:{href:"https://c.runoob.com/front-end/854/",target:"_blank",rel:"noopener noreferrer"}},[s._v("tool online"),a("OutboundLink")],1)])])],1)}),[],!1,null,null,null);a.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/144.9812ea81.js b/assets/js/144.9812ea81.js
new file mode 100644
index 00000000000..496a2a0aed3
--- /dev/null
+++ b/assets/js/144.9812ea81.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[144],{460:function(t,n,e){"use strict";e.r(n);var s=e(4),a=Object(s.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("blockquote",[t("p",[t("a",{attrs:{href:"https://github.com/shengcaishizhan/kkndme_tianya",target:"_blank",rel:"noopener noreferrer"}},[this._v("https://github.com/shengcaishizhan/kkndme_tianya"),t("OutboundLink")],1),this._v(" 待补充")])])])}),[],!1,null,null,null);n.default=a.exports}}]);
\ No newline at end of file
diff --git a/assets/js/145.acd0069a.js b/assets/js/145.acd0069a.js
new file mode 100644
index 00000000000..2ee525007d3
--- /dev/null
+++ b/assets/js/145.acd0069a.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[145],{461:function(t,a,r){"use strict";r.r(a);var s=r(4),e=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("blockquote",[a("p",[t._v("娥姐职场分享的提高效率的 5 个关键点, "),a("a",{attrs:{href:"https://www.bilibili.com/video/BV1JY4y1b7wC?spm_id_from=333.999.0.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("原视频链接"),a("OutboundLink")],1)])]),t._v(" "),a("h2",{attrs:{id:"_5-个关键点"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5-个关键点"}},[t._v("#")]),t._v(" 5 个关键点")]),t._v(" "),a("h3",{attrs:{id:"一、输出倒逼输入"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#一、输出倒逼输入"}},[t._v("#")]),t._v(" 一、输出倒逼输入")]),t._v(" "),a("h3",{attrs:{id:"二、提炼模型"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#二、提炼模型"}},[t._v("#")]),t._v(" 二、提炼模型")]),t._v(" "),a("p",[t._v("从现象中提取模型, 用模型思考问题和解法")]),t._v(" "),a("h3",{attrs:{id:"三、利用工具-解放自己的大脑"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#三、利用工具-解放自己的大脑"}},[t._v("#")]),t._v(" 三、利用工具: 解放自己的大脑")]),t._v(" "),a("p",[t._v("把我们的大脑从繁琐的事务解放出来, 只去记忆和思考更加重要的事情")]),t._v(" "),a("h3",{attrs:{id:"四、研究自己运行规律-找到让自己学习工作、效率更高的方法"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#四、研究自己运行规律-找到让自己学习工作、效率更高的方法"}},[t._v("#")]),t._v(" 四、研究自己运行规律, 找到让自己学习工作、效率更高的方法")]),t._v(" "),a("p",[t._v("要具备自我观察和迭代的意识, 这样才能持续找到提升效率的机会")]),t._v(" "),a("h3",{attrs:{id:"五、成本可控-释放善意"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#五、成本可控-释放善意"}},[t._v("#")]),t._v(" 五、成本可控, 释放善意")])])}),[],!1,null,null,null);a.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/146.e21fad72.js b/assets/js/146.e21fad72.js
new file mode 100644
index 00000000000..7b0202ebf0a
--- /dev/null
+++ b/assets/js/146.e21fad72.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[146],{462:function(r,e,t){"use strict";t.r(e);var n=t(4),a=Object(n.a)({},(function(){var r=this,e=r._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":r.$parent.slotKey}},[e("h2",{attrs:{id:"推荐"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#推荐"}},[r._v("#")]),r._v(" 推荐")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://panjiachen.github.io/awesome-bookmarks/",target:"_blank",rel:"noopener noreferrer"}},[r._v("panjiachen"),e("OutboundLink")],1),r._v(" by 花裤衩")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.code-nav.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("编程导航"),e("OutboundLink")],1),r._v(" by 程序员鱼皮")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://r2coding.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("编程自学之路"),e("OutboundLink")],1),r._v(" by 程序羊")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://gitee.com/jishupang/web_atlas",target:"_blank",rel:"noopener noreferrer"}},[r._v("前端知识图谱+B 站资源整合"),e("OutboundLink")],1),r._v(" by 技术胖")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://shengxinjing.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("大圣编程自学网"),e("OutboundLink")],1),r._v(" by 大圣")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://devtool.tech/",target:"_blank",rel:"noopener noreferrer"}},[r._v("开发者武器库"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.fly63.com/tool/home.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("工具大全"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://c.runoob.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("菜鸟工具"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/timqian/chinese-independent-blogs",target:"_blank",rel:"noopener noreferrer"}},[r._v("chinese-independent-blogs*"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://sideproject.guide/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Side Project 指南*"),e("OutboundLink")],1),r._v(" 用代码建造一些小工具")])]),r._v(" "),e("h2",{attrs:{id:"国外技术资讯"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#国外技术资讯"}},[r._v("#")]),r._v(" 国外技术资讯")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://news.ycombinator.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("hackernews"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"成长规范"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#成长规范"}},[r._v("#")]),r._v(" 成长规范")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md",target:"_blank",rel:"noopener noreferrer"}},[r._v("提问的智慧"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/Tencent/secguide/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Tencent-代码安全指南"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.zhihu.com/question/276356727",target:"_blank",rel:"noopener noreferrer"}},[r._v("知乎-如何减少团队的低质量代码?"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://mp.weixin.qq.com/s/Dl7umd-Z3QuvOwzjmy3Z4w",target:"_blank",rel:"noopener noreferrer"}},[r._v("大淘宝-如何提高代码质量"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"ai"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#ai"}},[r._v("#")]),r._v(" "),e("RouterLink",{attrs:{to:"/pages/df21f9/"}},[r._v("ai")])],1),r._v(" "),e("h2",{attrs:{id:"github-主页"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#github-主页"}},[r._v("#")]),r._v(" github 主页")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/timqian",target:"_blank",rel:"noopener noreferrer"}},[r._v("timqian"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"android"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#android"}},[r._v("#")]),r._v(" Android")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://developer.android.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("Android developer"),e("OutboundLink")],1),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://source.android.com/docs/core?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[r._v("Android 系统核心主题*"),e("OutboundLink")],1)])])]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.android.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("android 官网"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"http://androidxref.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("androidxref"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"文档"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#文档"}},[r._v("#")]),r._v(" 文档")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web",target:"_blank",rel:"noopener noreferrer"}},[r._v("MDN"),e("OutboundLink")],1),r._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects",target:"_blank",rel:"noopener noreferrer"}},[r._v("MDN-JS 标准内置对象"),e("OutboundLink")],1),r._v(" Web 技术权威文档")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://devdocs.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("DevDocs"),e("OutboundLink")],1),r._v(" Web 开发技术文档, 非常不错的学习手册!")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://zh.javascript.info",target:"_blank",rel:"noopener noreferrer"}},[r._v("现代 JavaScript 教程"),e("OutboundLink")],1),r._v(" 以最新标准为基准的 JS 教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://wangdoc.com/javascript/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ES5 教程"),e("OutboundLink")],1),r._v(" 阮一峰的 JS 教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://es6.ruanyifeng.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ES6 教程"),e("OutboundLink")],1),r._v(" 阮一峰的 ES6 教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://wangdoc.com/bash/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Bash 脚本教程"),e("OutboundLink")],1),r._v(" 阮一峰编写")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.ecma-international.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ECMA"),e("OutboundLink")],1),r._v(" ECMA 官网")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.runoob.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("菜鸟教程"),e("OutboundLink")],1),r._v(" 涵盖多种语言的初级教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://cloud.tencent.com/developer/devdocs",target:"_blank",rel:"noopener noreferrer"}},[r._v("腾讯云开发者手册"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"社区"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#社区"}},[r._v("#")]),r._v(" 社区")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Github"),e("OutboundLink")],1),r._v(" 程序员同性交友社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://juejin.im/",target:"_blank",rel:"noopener noreferrer"}},[r._v("掘金"),e("OutboundLink")],1),r._v(" 一个帮助开发者成长的社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.jianshu.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("简书"),e("OutboundLink")],1),r._v(" 有很多频道的创作社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://segmentfault.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("思否"),e("OutboundLink")],1),r._v(" 解决技术问题的社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://stackoverflow.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("stack overflow"),e("OutboundLink")],1),r._v(" 同上, 外网的")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.infoq.cn/topic/Front-end",target:"_blank",rel:"noopener noreferrer"}},[r._v("InfoQ"),e("OutboundLink")],1),r._v(" 促进软件开发及相关领域知识与创新的传播")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.v2ex.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("V2EX"),e("OutboundLink")],1),r._v(" 创意工作者们的社区")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://mo.fish",target:"_blank",rel:"noopener noreferrer"}},[r._v("鱼塘热榜"),e("OutboundLink")],1),r._v(" 划水网站, 收集了很多网站, 当天热门文章")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://maliquankai.com/designnav/",target:"_blank",rel:"noopener noreferrer"}},[r._v("码力全开资源库"),e("OutboundLink")],1),r._v(" 很全很强大, 独立开发者/设计干货/优质利器/工具资源...")])]),r._v(" "),e("h3",{attrs:{id:"社区互动"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#社区互动"}},[r._v("#")]),r._v(" 社区互动")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://gitter.im/home/explore",target:"_blank",rel:"noopener noreferrer"}},[r._v("gitter"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://txc.qq.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("兔小巢"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"技巧"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#技巧"}},[r._v("#")]),r._v(" 技巧")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://trends.google.com/trends",target:"_blank",rel:"noopener noreferrer"}},[r._v("Google 趋势"),e("OutboundLink")],1),r._v(" 查看某项技术或关键字的热度趋势, 可用于分析某项技术的发展前景, 或对比某两项技术的热度。")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://index.baidu.com/v2/index.html#/",target:"_blank",rel:"noopener noreferrer"}},[r._v("百度指数"),e("OutboundLink")],1),r._v(" 同上, 但百度的数据仅限国内。")])]),r._v(" "),e("h2",{attrs:{id:"博客"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#博客"}},[r._v("#")]),r._v(" 博客")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"http://www.ruanyifeng.com/blog/",target:"_blank",rel:"noopener noreferrer"}},[r._v("阮一峰的网络日志"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.samanthaming.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("samanthaming"),e("OutboundLink")],1),r._v(" 对前端小知识点的总结, 并为每个知识点制作精美的小卡片。")])]),r._v(" "),e("h2",{attrs:{id:"电子书"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#电子书"}},[r._v("#")]),r._v(" 电子书")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://ebook.hep.com.cn/ebooks/h5/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("高教书苑"),e("OutboundLink")],1),r._v(" 高等教育出版社的书籍, 包含多种学科。\n")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://sobooks.cc/",target:"_blank",rel:"noopener noreferrer"}},[r._v("SoBooks"),e("OutboundLink")],1),r._v(" 免费的电子书资源网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.shidianguji.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("识典古籍"),e("OutboundLink")],1),r._v(" 古籍数字化平台")])]),r._v(" "),e("h2",{attrs:{id:"优秀文章"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#优秀文章"}},[r._v("#")]),r._v(" 优秀文章")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://coolshell.cn/articles/21672.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("我做系统架构的一些原则"),e("OutboundLink")],1),r._v(" 作者对系统架构的方法论总结")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://coolshell.cn/articles/11656.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("开发团队的效率"),e("OutboundLink")],1),r._v(" WatchDog 的架构模式不应该滥用")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://juejin.im/post/5d4d0ec651882549594e7293",target:"_blank",rel:"noopener noreferrer"}},[r._v("灵活运用 CSS 开发技巧"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://ishadeed.com/article/defensive-css/",target:"_blank",rel:"noopener noreferrer"}},[r._v("防御性 CSS"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/shengcaishizhan/kkndme_tianya",target:"_blank",rel:"noopener noreferrer"}},[r._v("天涯 kkndme 神贴"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"视频"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#视频"}},[r._v("#")]),r._v(" 视频")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.bilibili.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("bilibili"),e("OutboundLink")],1),r._v(" B 站, 上面很多免费教学视频")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.imooc.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("慕课网"),e("OutboundLink")],1),r._v(" 实战视频教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.miaov.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("妙味课堂"),e("OutboundLink")],1),r._v(" 比较系统的前端入门视频教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.icourse163.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("中国大学 MOOC"),e("OutboundLink")],1),r._v(" 涵盖计算机、外语、心理学等专业免费课程")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://le.ouchn.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("终身教育平台"),e("OutboundLink")],1),r._v(" 涵盖生活、兴趣、职场、技能、老年、学历等免费课程")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://egghead.io",target:"_blank",rel:"noopener noreferrer"}},[r._v("egghead"),e("OutboundLink")],1),r._v(" 质量还不错的短视频教程, 外网")])]),r._v(" "),e("h2",{attrs:{id:"github"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#github"}},[r._v("#")]),r._v(" Github")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://repobeats.axiom.co/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Repobeats"),e("OutboundLink")],1),r._v(" 生成仓库的动态数据统计图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://git.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("github 短域名服务"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://shields.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("shields"),e("OutboundLink")],1),r._v(" 徽章图标")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://wangchujiang.com/github-rank/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("followers 全球排名"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://star-history.t9t.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("star-history"),e("OutboundLink")],1),r._v(" 展示一个项目 Stars 增长曲线")])]),r._v(" "),e("h2",{attrs:{id:"评论系统"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#评论系统"}},[r._v("#")]),r._v(" 评论系统")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://giscus.app/zh-CN",target:"_blank",rel:"noopener noreferrer"}},[r._v("giscus"),e("OutboundLink")],1),r._v(" 由 "),e("a",{attrs:{href:"https://docs.github.com/en/discussions",target:"_blank",rel:"noopener noreferrer"}},[r._v("GitHub Discussions"),e("OutboundLink")],1),r._v(" 驱动的评论系统")])]),r._v(" "),e("h2",{attrs:{id:"前端小工具"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#前端小工具"}},[r._v("#")]),r._v(" 前端小工具")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://caniuse.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Can I use"),e("OutboundLink")],1),r._v(" 查看属性和方法的兼容性")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://30secondsofcode.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("30 seconds of code"),e("OutboundLink")],1),r._v(" 收集了许多有用的代码小片段")])]),r._v(" "),e("h2",{attrs:{id:"代码编辑"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#代码编辑"}},[r._v("#")]),r._v(" 代码编辑")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://codepen.io",target:"_blank",rel:"noopener noreferrer"}},[r._v("codepen"),e("OutboundLink")],1),r._v(" 在线代码编辑与演示")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://codesandbox.io",target:"_blank",rel:"noopener noreferrer"}},[r._v("codesandbox"),e("OutboundLink")],1),r._v(" 内嵌 VSCode 的在线 IDE")])]),r._v(" "),e("h2",{attrs:{id:"emoji-表情"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#emoji-表情"}},[r._v("#")]),r._v(" Emoji 表情")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://emojipedia.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("emoji 表情"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.webfx.com/tools/emoji-cheat-sheet",target:"_blank",rel:"noopener noreferrer"}},[r._v("emoji 表情备忘录"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://translate.yandex.com/?lang=zh-emj",target:"_blank",rel:"noopener noreferrer"}},[r._v("根据文本匹配 emoji"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/carloscuesta/gitmoji",target:"_blank",rel:"noopener noreferrer"}},[r._v("gitmoji"),e("OutboundLink")],1),r._v(" 通过 emoji 表达 git 的操作内容")])]),r._v(" "),e("blockquote",[e("p",[r._v("在任意输入框快速打开 emoji 表情方法: "),e("br"),r._v("\nWindows 系统下按"),e("kbd",[r._v("Win")]),r._v(" + "),e("kbd",[r._v(".")]),e("br"),r._v("\nMac 系统下按"),e("kbd",[r._v("Control")]),r._v(" + "),e("kbd",[r._v("Command")]),r._v(" + "),e("kbd",[r._v("空格")])])]),r._v(" "),e("h2",{attrs:{id:"图片工具"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#图片工具"}},[r._v("#")]),r._v(" 图片工具")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://tinypng.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("tinypng 图片压缩"),e("OutboundLink")],1),r._v(" 压缩 png 很有用")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://devtool.tech/tiny-image",target:"_blank",rel:"noopener noreferrer"}},[r._v("微图"),e("OutboundLink")],1),r._v(" 浏览器端图片压缩, 不会上传图片到服务器")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://squoosh.app/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Squoosh"),e("OutboundLink")],1),r._v(" 谷歌出品在线免费图片压缩工具(jpg、png 等,压缩效果比 tinypng 稍好)")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://waifu2x.udp.jp/",target:"_blank",rel:"noopener noreferrer"}},[r._v("waifu2x"),e("OutboundLink")],1),r._v(" 通过卷积网络放大图片")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://vectormagic.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("vectormagic"),e("OutboundLink")],1),r._v(" 转换矢量图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.vectorizer.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("vectorizer"),e("OutboundLink")],1),r._v(" 真正的 png 转 svg 神器")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://photo.opencool.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("在线 AI 图片处理"),e("OutboundLink")],1),r._v(" 黑白修复、无损放大、动漫化、铅笔画等。")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.remove.bg/zh",target:"_blank",rel:"noopener noreferrer"}},[r._v("remove"),e("OutboundLink")],1),r._v(" AI 抠图(抠背景)")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.magiceraser.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("magic eraser"),e("OutboundLink")],1),r._v(" AI 抠图(抠前景)")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/nadermx/backgroundremover",target:"_blank",rel:"noopener noreferrer"}},[r._v("backgroundremover"),e("OutboundLink")],1),r._v(" 又一个抠图的")])]),r._v(" "),e("h2",{attrs:{id:"svg"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#svg"}},[r._v("#")]),r._v(" SVG")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://e2.cool/",target:"_blank",rel:"noopener noreferrer"}},[r._v("svg 编辑器-E2.Cool"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://x.ipaiban.com/login",target:"_blank",rel:"noopener noreferrer"}},[r._v("svg 编辑器-i 排版"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"音视频工具"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#音视频工具"}},[r._v("#")]),r._v(" 音视频工具")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://app.xunjieshipin.com/video-converter/",target:"_blank",rel:"noopener noreferrer"}},[r._v("迅捷视频转换器"),e("OutboundLink")],1),r._v(" 在线转换各种视频格式")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://app.xunjieshipin.com/video-converter/",target:"_blank",rel:"noopener noreferrer"}},[r._v("迅捷音频转换器"),e("OutboundLink")],1),r._v(" 在线转换各种音频格式")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://mp3cut.net/cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("修剪音频"),e("OutboundLink")],1),r._v(" 在线修剪或剪切任何音频文件")])]),r._v(" "),e("h2",{attrs:{id:"思维导图"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#思维导图"}},[r._v("#")]),r._v(" 思维导图")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.processon.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("processon 在线作图"),e("OutboundLink")],1),r._v(" 流程图、思维导图、原型图等")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://naotu.baidu.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("百度脑图"),e("OutboundLink")],1),r._v(" 思维导图")]),r._v(" "),e("li",[e("a",{attrs:{href:"plectica.com"}},[r._v("plectica")]),r._v(" 绘制知识图谱")])]),r._v(" "),e("h2",{attrs:{id:"css"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#css"}},[r._v("#")]),r._v(" CSS")]),r._v(" "),e("ul",[e("li",[e("p",[e("a",{attrs:{href:"https://juejin.cn/post/7030572979868139551?utm_source=gold_browser_extension",target:"_blank",rel:"noopener noreferrer"}},[r._v("各种 CSS 生成器和 JS 代码片段"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://css-tricks.neatbang.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS Tricks"),e("OutboundLink")],1),r._v(" CSS 技巧收集与演示")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://neumorphism.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS 生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://www.colorzilla.com/gradient-editor/",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS 渐变生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://www.html.cn/tool/css3Preview/Box-Shadow.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS3-Box Shadow(阴影)"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://cubic-bezier.com",target:"_blank",rel:"noopener noreferrer"}},[r._v("贝塞尔曲线生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://www.heropatterns.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("花纹背景生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://github.com/bansal-io/pattern.css",target:"_blank",rel:"noopener noreferrer"}},[r._v("花纹背景-pattern.css"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://bennettfeely.com/ztext/",target:"_blank",rel:"noopener noreferrer"}},[r._v("3D 字体"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://css-tricks.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("css-tricks"),e("OutboundLink")],1),r._v(" css 技巧文章")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://lhammer.cn/You-need-to-know-css/#/zh-cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("You-need-to-know-css"),e("OutboundLink")],1),r._v(" CSS 的各种 DEMO, 很全")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://animista.net/",target:"_blank",rel:"noopener noreferrer"}},[r._v("animista"),e("OutboundLink")],1),r._v(" CSS 动画可视化工具, 复制代码就能用")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://navnav.co/",target:"_blank",rel:"noopener noreferrer"}},[r._v("navnav"),e("OutboundLink")],1),r._v(" 各种炫酷的 CSS 动画组件")])])]),r._v(" "),e("h2",{attrs:{id:"cdn-加速"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#cdn-加速"}},[r._v("#")]),r._v(" CDN 加速")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"http://www.jsdelivr.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("jsDelivr"),e("OutboundLink")],1),r._v(" 国外的一家优秀的公共 CDN 服务提供商")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://unpkg.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("unpkg"),e("OutboundLink")],1),r._v(" cdn 服务")])]),r._v(" "),e("h2",{attrs:{id:"正则"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#正则"}},[r._v("#")]),r._v(" 正则")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://regex101.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("正则可视化"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://ihateregex.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("iHateRegex"),e("OutboundLink")],1),r._v(" 正则搜索, 细节做得很好")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/qdlaoyao/js-regex-mini-book",target:"_blank",rel:"noopener noreferrer"}},[r._v("正则迷你书"),e("OutboundLink")],1),r._v(" 学习正则的小手册")])]),r._v(" "),e("h2",{attrs:{id:"其他"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[r._v("#")]),r._v(" 其他")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://ipcmen.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Linux 命令手册"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://carbon.now.sh/",target:"_blank",rel:"noopener noreferrer"}},[r._v("carbon 代码图片生成器"),e("OutboundLink")],1),r._v(" 生成好看的代码图片")])]),r._v(" "),e("h2",{attrs:{id:"设计"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#设计"}},[r._v("#")]),r._v(" 设计")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"http://chuangzaoshi.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("创造师导航"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"http://hao.uisdc.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("设计师网址导航"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.remove.bg/zh",target:"_blank",rel:"noopener noreferrer"}},[r._v("remove"),e("OutboundLink")],1),r._v(" AI 抠图, 抠图算法很厉害")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.manypixels.co/gallery/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Manypixels"),e("OutboundLink")],1),r._v(" 插画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://undraw.co/illustrations",target:"_blank",rel:"noopener noreferrer"}},[r._v("Undraw"),e("OutboundLink")],1),r._v(" 插画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://storytale.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("storytale"),e("OutboundLink")],1),r._v(" 插画, 种类丰富, 包含 3D 插画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://uimovement.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("uimovement"),e("OutboundLink")],1),r._v(" 能从这个网站找到不少动画交互的灵感")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.awwwards.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("awwwards"),e("OutboundLink")],1),r._v("是一个一个专门为设计精美的网站以及富有创意的网站颁奖的网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://dribbble.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("dribbble"),e("OutboundLink")],1),r._v(" 经常能在上面找到很多有创意好看的 gif 或者图片")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.behance.net/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Bēhance"),e("OutboundLink")],1),r._v(" dribbble 是设计师的微博, Bēhance 是设计师的博客")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://logojoy.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Logojoy"),e("OutboundLink")],1),r._v(" 使用 ai 做 logo 的网站, 做出来的 logo 质量还不错。")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://brandmark.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("brandmark"),e("OutboundLink")],1),r._v(" 另一个在线制作 logo 网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://instantlogodesign.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("instant"),e("OutboundLink")],1),r._v(" 又一个 logo 制作网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.namecheap.com/logo-maker/app/",target:"_blank",rel:"noopener noreferrer"}},[r._v("namecheap"),e("OutboundLink")],1),r._v("又一个 logo 制作网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.designevo.com/logo-maker/",target:"_blank",rel:"noopener noreferrer"}},[r._v("logo-maker"),e("OutboundLink")],1),r._v(" 又一个 logo 制作网站 这个更简单点 就是选模板之后微调")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://coolors.co/",target:"_blank",rel:"noopener noreferrer"}},[r._v("coolors"),e("OutboundLink")],1),r._v(" 帮你在线配色的网站 你能找到不少配色灵感")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://colorhunt.co/",target:"_blank",rel:"noopener noreferrer"}},[r._v("colorhunt"),e("OutboundLink")],1),r._v(" 另一个配色网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://uigradients.com/#SummerDog",target:"_blank",rel:"noopener noreferrer"}},[r._v("uigradients"),e("OutboundLink")],1),r._v(" 渐变色网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.designcap.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("designcap"),e("OutboundLink")],1),r._v(" 在线海报设计")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://flatuicolors.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Flat UI 色表"),e("OutboundLink")],1),r._v(" Flat UI 色表")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.0to255.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("0to255"),e("OutboundLink")],1),r._v(" 颜色梯度")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/mikolajdobrucki/ikonate",target:"_blank",rel:"noopener noreferrer"}},[r._v("Ikonate"),e("OutboundLink")],1),r._v(" 提供免费的图标 icons")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://remixicon.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("remixicon"),e("OutboundLink")],1),r._v(" 又一个提供免费图标 icons")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/feathericons/feather",target:"_blank",rel:"noopener noreferrer"}},[r._v("feather"),e("OutboundLink")],1),r._v(" 免费的 icons")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/arcticicestudio/nord",target:"_blank",rel:"noopener noreferrer"}},[r._v("nord"),e("OutboundLink")],1),r._v(" 北欧性冷淡风主题配色")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://unsplash.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Unsplash"),e("OutboundLink")],1),r._v(" 提供免费的高清图片")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.pexels.com/zh-cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Pexels"),e("OutboundLink")],1),r._v(" 提供免费的高清图片")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://colorkitty.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("colorkitty"),e("OutboundLink")],1),r._v(" 从你的图片中提取配色")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://design.youzan.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("design.youzan"),e("OutboundLink")],1),r._v(" 有赞设计原则")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.iconfont.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("iconfont"),e("OutboundLink")],1),r._v(" 阿里巴巴矢量图标库")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://undraw.co/illustrations",target:"_blank",rel:"noopener noreferrer"}},[r._v("undraw"),e("OutboundLink")],1),r._v(" 免费的矢量插画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://icomoon.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("icomoon"),e("OutboundLink")],1),r._v(" 矢量图标库")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://cssicon.space/#/",target:"_blank",rel:"noopener noreferrer"}},[r._v("cssicon"),e("OutboundLink")],1),r._v(" 所有的 icon 都是纯 css 画的 缺点: icon 不够多")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://apps.eky.hk/css-triangle-generator/",target:"_blank",rel:"noopener noreferrer"}},[r._v("CSS triangle generator"),e("OutboundLink")],1),r._v(" 帮你快速用 css 做出三角形")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://bennettfeely.com/clippy/",target:"_blank",rel:"noopener noreferrer"}},[r._v("clippy"),e("OutboundLink")],1),r._v(" 在线帮你使用 css clip-path 做出各种形状的图形")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://picsum.photos/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Lorem Picsum"),e("OutboundLink")],1),r._v(" 提供免费的占位图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.canva.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Canva 可画"),e("OutboundLink")],1),r._v(" 生成插画、封面、海报、头像等")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://error404.fun/",target:"_blank",rel:"noopener noreferrer"}},[r._v("404 页"),e("OutboundLink")],1),r._v(" 404 页素材")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://collectui.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("collectui"),e("OutboundLink")],1),r._v(" 按功能组件分类的设计图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://smartmockups.com/zh",target:"_blank",rel:"noopener noreferrer"}},[r._v("smartmockups"),e("OutboundLink")],1),r._v(" 产品模板生成工具")])]),r._v(" "),e("h2",{attrs:{id:"图库"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#图库"}},[r._v("#")]),r._v(" 图库")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://uigradients.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("uigradients"),e("OutboundLink")],1),r._v(" 渐变色生成工具")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.freepik.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("freepik"),e("OutboundLink")],1),r._v(" banner 图库")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://www.51yuansu.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("觅元素"),e("OutboundLink")],1),r._v("一天免费下载十张 psd(免抠元素)")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.gaoding.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("搞定设计"),e("OutboundLink")],1),r._v(" 可以抠图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.vectorizer.io/",target:"_blank",rel:"noopener noreferrer"}},[r._v("vectorizer"),e("OutboundLink")],1),r._v(" 真正的 png 转 svg 神器")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.zcool.com.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("站酷"),e("OutboundLink")],1),r._v(" 国内优秀的设计作品展示")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://huaban.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("花瓣"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://huke88.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("虎克"),e("OutboundLink")],1),r._v(" ps 学习教程")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://themes.muffingroup.com/be/splash/",target:"_blank",rel:"noopener noreferrer"}},[r._v("beTheme"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.ui.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("UI 中国"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://alpha.wallhaven.cc/",target:"_blank",rel:"noopener noreferrer"}},[r._v("wallhaven"),e("OutboundLink")],1),r._v(" 壁纸网站-")])]),r._v(" "),e("h2",{attrs:{id:"_3d"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3d"}},[r._v("#")]),r._v(" 3D")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://sketchfab.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("sketchfab"),e("OutboundLink")],1),r._v(" 3D 模型")])]),r._v(" "),e("h2",{attrs:{id:"交互"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#交互"}},[r._v("#")]),r._v(" 交互")]),r._v(" "),e("ul",[e("li",[e("p",[e("a",{attrs:{href:"http://aliscued.lofter.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("微交互"),e("OutboundLink")],1),r._v(" 里面收集了市面上很多很好的微交互例子 值得学习")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://littlebigdetails.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Little Big Details"),e("OutboundLink")],1),r._v(" 同上, 一个国外微交互汇集网站")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://cruip.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("cruip"),e("OutboundLink")],1),r._v(" 登录页的各种页面设计, 可以免费下载模板")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://comixify.ii.pw.edu.pl/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Comixify"),e("OutboundLink")],1),r._v(" 一个波兰团队做了非常好玩的工具, 可以把视频自动转成漫画, 上图是他们提供的 demo, 效果很棒。")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://github.com/bui/taiko-web",target:"_blank",rel:"noopener noreferrer"}},[r._v("taiko-web"),e("OutboundLink")],1),r._v(" 太鼓达人网页版 只能说很 6")])])]),r._v(" "),e("h2",{attrs:{id:"有趣"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#有趣"}},[r._v("#")]),r._v(" 有趣")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://pranx.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("电脑恶搞"),e("OutboundLink")],1),r._v(" 收集了一些恶搞小网页, 比如 xp 系统蓝屏、黑客界面等")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://neocities.org/browse",target:"_blank",rel:"noopener noreferrer"}},[r._v("neocities"),e("OutboundLink")],1),r._v(" 上面托管了很多有趣的网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://fuun.fun/",target:"_blank",rel:"noopener noreferrer"}},[r._v("奇趣网站收藏家"),e("OutboundLink")],1),r._v(" 收藏了很多有趣的网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://game.xugaoyi.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("FC 在线模拟器(小霸王游戏机)"),e("OutboundLink")],1),r._v(" 童年回忆")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://www.baidu-x.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("帮你百度一下"),e("OutboundLink")],1),r._v(" 可以 "),e("a",{attrs:{href:"http://www.baidu-x.com/?q=%E5%92%8C%E8%B0%90%E6%9C%89%E7%88%B1%E5%AF%8C%E5%BC%BA",target:"_blank",rel:"noopener noreferrer"}},[r._v("点我测试一下"),e("OutboundLink")],1),r._v("-")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://lmgtfy.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("国际版"),e("OutboundLink")],1),r._v(" 同"),e("code",[r._v("帮我百度一下")]),r._v("-"),e("a",{attrs:{href:"http://lmgtfy.com/?q=a",target:"_blank",rel:"noopener noreferrer"}},[r._v("点我测试一下"),e("OutboundLink")],1),r._v("-")]),r._v(" "),e("li",[e("a",{attrs:{href:"http://matthewrayfield.com/articles/animating-urls-with-javascript-and-emojis/#%F0%9F%8C%96",target:"_blank",rel:"noopener noreferrer"}},[r._v("URL 地址播放 Emojis 动画"),e("OutboundLink")],1),r._v(" 在地址栏里面播放 emoji")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://cantunsee.space/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Can't Unsee"),e("OutboundLink")],1),r._v(" 强烈建议前端、客户端、UI 开发的同学玩下, 检查一下自己对设计稿的敏感度怎么样")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://talk.swift.gg/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ggtalk"),e("OutboundLink")],1),r._v(" 平时一直在听的一个技术博客")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/Blankj/awesome-comment",target:"_blank",rel:"noopener noreferrer"}},[r._v("awesome-comment"),e("OutboundLink")],1),r._v(" 里面收集了很多有趣的代码注释")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.text-image.com/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("text-img"),e("OutboundLink")],1),r._v(" 都将图片转化为 ascii 用来写注释")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://pessimistress.github.io/ascii/",target:"_blank",rel:"noopener noreferrer"}},[r._v("ascii video"),e("OutboundLink")],1),r._v(" 使用 ascii 编码生成视频动画")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/beizhedenglong/weird-fonts",target:"_blank",rel:"noopener noreferrer"}},[r._v("weird-fonts"),e("OutboundLink")],1),r._v(" 将普通字母转化为 特殊 unicode")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/epidemian/snake",target:"_blank",rel:"noopener noreferrer"}},[r._v("snake"),e("OutboundLink")],1),r._v(" 在地址栏里面玩贪吃蛇")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/yuanfux/zero-width-lib",target:"_blank",rel:"noopener noreferrer"}},[r._v("zero-width-lib"),e("OutboundLink")],1),r._v(" 利用零宽度字符实现 隐形水印、加密信息分享、逃脱词匹配, 很有创意")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.abbreviations.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("abbreviations"),e("OutboundLink")],1),r._v(" 查看一个简写是什么意思的网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://magi.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("magi"),e("OutboundLink")],1),r._v(" ai 搜索神器, 超屌")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.qmsjmfb.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("在线取名"),e("OutboundLink")],1),r._v(" 解决取名难问题, 超多名字生成")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://collet66.web.fc2.com/nijisanji/index.html",target:"_blank",rel:"noopener noreferrer"}},[r._v("像素画 GIF"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://uchinoko-maker.jp/",target:"_blank",rel:"noopener noreferrer"}},[r._v("猫咪生成器"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"生成器"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#生成器"}},[r._v("#")]),r._v(" 生成器")]),r._v(" "),e("ul",[e("li",[e("p",[e("a",{attrs:{href:"https://toonme.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("卡通头像生成器"),e("OutboundLink")],1),r._v(" 上传真人头像生成卡通头像")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://www.artbreeder.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("artbreeder"),e("OutboundLink")],1),r._v(" 动漫图生成真人图像")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://neal.fun/ambient-chaos/",target:"_blank",rel:"noopener noreferrer"}},[r._v("声音生成器"),e("OutboundLink")],1),r._v(" 生成下雨、咖啡厅、海浪、火车等声音, 可几种声音合成")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://zzkia.noddl.me:8020/",target:"_blank",rel:"noopener noreferrer"}},[r._v("诺基亚短信图片生成器"),e("OutboundLink")],1)])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://zfb.xugaoyi.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("到账语音生成器"),e("OutboundLink")],1),r._v(" 支付宝到账 1 亿元")])])]),r._v(" "),e("h2",{attrs:{id:"元宇宙"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#元宇宙"}},[r._v("#")]),r._v(" 元宇宙")]),r._v(" "),e("p",[r._v("符合元宇宙特征的几个网站, 允许用户拥有虚拟土地, 在上面构建自己的世界:")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.sandbox.game/cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("沙盒"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://somniumspace.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("梦境空间"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://market.decentraland.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Decentraland"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"教程"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#教程"}},[r._v("#")]),r._v(" 教程")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://egghead.io/courses/execute-npm-package-binaries-with-the-npx-package-runner",target:"_blank",rel:"noopener noreferrer"}},[r._v("npx"),e("OutboundLink")],1),r._v(" 教你怎么合理的使用 npx")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.hacksplaining.com/lessons",target:"_blank",rel:"noopener noreferrer"}},[r._v("hacksplaining"),e("OutboundLink")],1),r._v(" 网络安全学习网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/mcuking/mobile-web-best-practice",target:"_blank",rel:"noopener noreferrer"}},[r._v("mobile-web-best-practice"),e("OutboundLink")],1),r._v(" 移动 web 最佳实践")])]),r._v(" "),e("h2",{attrs:{id:"产品"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#产品"}},[r._v("#")]),r._v(" 产品")]),r._v(" "),e("ul",[e("li",[e("p",[e("a",{attrs:{href:"https://www.producthunt.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Product Hunt"),e("OutboundLink")],1),r._v(" 好产品推荐")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"http://www.pmdaniu.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("产品大牛"),e("OutboundLink")],1),r._v(" 什么有很多完整的产品原型可以借鉴")])]),r._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://modao.cc/pricing",target:"_blank",rel:"noopener noreferrer"}},[r._v("磨刀"),e("OutboundLink")],1),r._v(" 快速出 ui 原型")])])]),r._v(" "),e("h2",{attrs:{id:"实用"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#实用"}},[r._v("#")]),r._v(" 实用")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://webden.dev/",target:"_blank",rel:"noopener noreferrer"}},[r._v("webden"),e("OutboundLink")],1),r._v(" 在线网页编辑器, 轻便快捷")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://browser-update.org/",target:"_blank",rel:"noopener noreferrer"}},[r._v("browser-update"),e("OutboundLink")],1),r._v(" 浏览器版本更新提示插件")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://admin.typeform.com/signup",target:"_blank",rel:"noopener noreferrer"}},[r._v("typeform"),e("OutboundLink")],1),r._v(" 一个国外的在线调查问卷网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.videofk.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("VideoFk"),e("OutboundLink")],1),r._v(" VideoFk 视频在线解析下载")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.allhistory.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("全历史"),e("OutboundLink")],1),r._v(" 历史内容聚合网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.uzer.me/",target:"_blank",rel:"noopener noreferrer"}},[r._v("UzerMe"),e("OutboundLink")],1),r._v(" 云端办公工具")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://sobooks.cc/",target:"_blank",rel:"noopener noreferrer"}},[r._v("SoBooks"),e("OutboundLink")],1),r._v(" 强大的电子书资源网站")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.gaoding.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("稿定设计"),e("OutboundLink")],1),r._v(" 键式设计工具+智能抠图")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://dalipan.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("大力盘"),e("OutboundLink")],1),r._v(" 百度网盘搜索")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.macbl.com/app/internet/enfi",target:"_blank",rel:"noopener noreferrer"}},[r._v("ENFI 下载器"),e("OutboundLink")],1),r._v(" 不限速下载器")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.laihua.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("来画视频"),e("OutboundLink")],1),r._v(" 像做 PPT 一样做短视频")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.arkie.cn/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Arkie 海报制作工具"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"http://www.ypppt.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("优品 PPT"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"http://www.tretars.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("比格 PPT"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.pexels.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("高清免费图片"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://unsplash.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("高清免费图片 2"),e("OutboundLink")],1)]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.shapedivider.app/",target:"_blank",rel:"noopener noreferrer"}},[r._v("shapedivider"),e("OutboundLink")],1),r._v(" 生成波浪分隔线")]),r._v(" "),e("li",[e("a",{attrs:{href:"https://www.notion.so/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Notion"),e("OutboundLink")],1),r._v(" 知识库、快速笔记、TaskList、日记、读书清单, 各种类型, 应有尽有")])]),r._v(" "),e("h2",{attrs:{id:"talk"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#talk"}},[r._v("#")]),r._v(" Talk")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/peerigon/talks",target:"_blank",rel:"noopener noreferrer"}},[r._v("peerigon-talks"),e("OutboundLink")],1),r._v(" 收集了不少有意思的 talks")])]),r._v(" "),e("h2",{attrs:{id:"算法"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#算法"}},[r._v("#")]),r._v(" 算法")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/azl397985856/leetcode",target:"_blank",rel:"noopener noreferrer"}},[r._v("leetcode"),e("OutboundLink")],1),r._v(" 用 js 刷 leetcode")])]),r._v(" "),e("h2",{attrs:{id:"nginx"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#nginx"}},[r._v("#")]),r._v(" nginx")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.digitalocean.com/community/tools/nginx?global.app.lang=zhCN",target:"_blank",rel:"noopener noreferrer"}},[r._v("nginx 可视化配置工具"),e("OutboundLink")],1)])]),r._v(" "),e("h2",{attrs:{id:"生活"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#生活"}},[r._v("#")]),r._v(" 生活")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.ventusky.com/",target:"_blank",rel:"noopener noreferrer"}},[r._v("Ventusky"),e("OutboundLink")],1),r._v(" 风雨气温图")])]),r._v(" "),e("h2",{attrs:{id:"营销"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#营销"}},[r._v("#")]),r._v(" 营销")]),r._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.adguider.com/calendar",target:"_blank",rel:"noopener noreferrer"}},[r._v("营销日历"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=a.exports}}]);
\ No newline at end of file
diff --git a/assets/js/147.f821270d.js b/assets/js/147.f821270d.js
new file mode 100644
index 00000000000..8b586243692
--- /dev/null
+++ b/assets/js/147.f821270d.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[147],{463:function(t,e,r){"use strict";r.r(e);var n=r(4),o=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"海外求职"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#海外求职"}},[t._v("#")]),t._v(" 海外求职")]),t._v(" "),e("ul",[e("li",[t._v("website\n"),e("ul",[e("li",[e("a",{attrs:{href:"https://eleduck.com",target:"_blank",rel:"noopener noreferrer"}},[t._v("电鸭"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/ruanyf/weekly/issue/2960",target:"_blank",rel:"noopener noreferrer"}},[t._v("ryf谁在招人"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/vercel/next.js/discussions/44541",target:"_blank",rel:"noopener noreferrer"}},[t._v("who is hiring"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://remoteok.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("remoteok"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://justjoin.it",target:"_blank",rel:"noopener noreferrer"}},[t._v("justjoin.it"),e("OutboundLink")],1),t._v(": 主打欧洲市场的远程工作机会")]),t._v(" "),e("li",[e("a",{attrs:{href:"https://toptal.com",target:"_blank",rel:"noopener noreferrer"}},[t._v("toptal"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[t._v("other\n"),e("ul",[e("li",[e("a",{attrs:{href:"https://eleduck.com/posts/OGfxxl",target:"_blank",rel:"noopener noreferrer"}},[t._v("程序员海外 Remote 工作探索和总结"),e("OutboundLink")],1)])])])])])}),[],!1,null,null,null);e.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/148.812bfea9.js b/assets/js/148.812bfea9.js
new file mode 100644
index 00000000000..dde06a58b2c
--- /dev/null
+++ b/assets/js/148.812bfea9.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[148],{464:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/149.4b1f6d18.js b/assets/js/149.4b1f6d18.js
new file mode 100644
index 00000000000..f754aacaf4c
--- /dev/null
+++ b/assets/js/149.4b1f6d18.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[149],{465:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/15.222f035d.js b/assets/js/15.222f035d.js
new file mode 100644
index 00000000000..510032e1544
--- /dev/null
+++ b/assets/js/15.222f035d.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[15],{334:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/150.1ee6c71f.js b/assets/js/150.1ee6c71f.js
new file mode 100644
index 00000000000..02621f79494
--- /dev/null
+++ b/assets/js/150.1ee6c71f.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[150],{466:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/151.658bed6b.js b/assets/js/151.658bed6b.js
new file mode 100644
index 00000000000..5ba43f4f334
--- /dev/null
+++ b/assets/js/151.658bed6b.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[151],{467:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/152.2378f0f9.js b/assets/js/152.2378f0f9.js
new file mode 100644
index 00000000000..95f9ce9790d
--- /dev/null
+++ b/assets/js/152.2378f0f9.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[152],{468:function(t,a,e){"use strict";e.r(a);var r=e(4),s=Object(r.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"资源"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#资源"}},[t._v("#")]),t._v(" 资源")]),t._v(" "),a("p",[t._v("下载一个百度网盘, 登录自己的百度网盘 然后添加用户名: 英雄不问出路人 给师傅发送: ns 游戏然后会自动分享给你")]),t._v(" "),a("h3",{attrs:{id:"游戏下载"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#游戏下载"}},[t._v("#")]),t._v(" 游戏下载")]),t._v(" "),a("p",[t._v("下载游戏网址: "),a("a",{attrs:{href:"https://www.bibgame.com/sgame/",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.bibgame.com/sgame/"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("游戏年轮登陆账号: 用户名:"),a("code",[t._v("游戏年轮")]),t._v(" 密码: "),a("code",[t._v("liming123..")]),t._v(".切记请不要去修改密码, 如查询到有修改密码者, 不提供使用会员账号, 且我们也会把之前的密码重新注销, 会导致使用不了, 谢谢")]),t._v(" "),a("h4",{attrs:{id:"安装"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#安装"}},[t._v("#")]),t._v(" 安装")]),t._v(" "),a("p",[t._v("把下载好的游戏软件放在内存卡的游戏文件夹 GAMES 里面, 然后进入破解系统, 选择相册进入, 找到小\n女孩的头像进入, 选择内存卡安装, 找到游戏文件夹, 然后按照提示安装游戏即可。支持 nsp 和 xci 两种格式的游戏文件。安装游戏\n时内存卡里面剩余的内存需要比游戏本体大。")]),t._v(" "),a("h2",{attrs:{id:"安装游戏"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#安装游戏"}},[t._v("#")]),t._v(" 安装游戏")]),t._v(" "),a("blockquote",[a("p",[t._v("这里应该是已经破解过的游戏下载, 待验证")])]),t._v(" "),a("ol",[a("li",[t._v("关机拔出内存卡, 读卡器插上电脑。")]),t._v(" "),a("li",[t._v("下载 xci 或者 nsp 的游戏文件(不要下文件夹)到内存卡 agames 文件夹。")]),t._v(" "),a("li",[t._v("拔出内存卡, 插回游戏机。")]),t._v(" "),a("li",[t._v("破解系统相册进入 atmoxl 进行安装, 安装完安装包删除。")])]),t._v(" "),a("p",[t._v("【游戏文件名字不能是中文, 补丁及 DLC 安装方法和游戏安装方法一样】")]),t._v(" "),a("h2",{attrs:{id:"破解"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#破解"}},[t._v("#")]),t._v(" 破解")]),t._v(" "),a("ul",[a("li",[t._v("大气层破解: "),a("a",{attrs:{href:"https://video3.yangkeduo.com/i1/2020-08-11/0146c0c9ebf5b58958c9713c45e01898.mp4",target:"_blank",rel:"noopener noreferrer"}},[t._v("网址"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=s.exports}}]);
\ No newline at end of file
diff --git a/assets/js/153.cd789d5d.js b/assets/js/153.cd789d5d.js
new file mode 100644
index 00000000000..472da47f6d8
--- /dev/null
+++ b/assets/js/153.cd789d5d.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[153],{469:function(a,t,s){"use strict";s.r(t);var r=s(4),v=Object(r.a)({},(function(){var a=this,t=a._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[t("h2",{attrs:{id:"大纲"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#大纲"}},[a._v("#")]),a._v(" 大纲")]),a._v(" "),t("h3",{attrs:{id:"第一章-初遇"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第一章-初遇"}},[a._v("#")]),a._v(" 第一章: 初遇")]),a._v(" "),t("p",[a._v("小伟和小娟从小一起长大, 他们是邻居, 也是最好的朋友。每天放学后, 他们都会一起在花园里玩耍, 一起分享快乐和烦恼。小伟早已发现自己对小娟有着特殊的感情, 但还未敢表白。而小娟, 也在心里默默地暗恋着小伟。")]),a._v(" "),t("h3",{attrs:{id:"第二章-心动时刻"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二章-心动时刻"}},[a._v("#")]),a._v(" 第二章: 心动时刻")]),a._v(" "),t("p",[a._v("随着年龄的增长, 小伟开始逐渐明白自己对小娟的感情。一次偶然的相遇, 小娟为小伟修理掉了牙齿, 他们的手指不小心碰触, 让两颗年轻的心砰砰直跳。小伟决定要勇敢面对这份心动, 但他担心这样会让他们的友谊变得尴尬。")]),a._v(" "),t("h3",{attrs:{id:"第三章-情窦初开"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第三章-情窦初开"}},[a._v("#")]),a._v(" 第三章: 情窦初开")]),a._v(" "),t("p",[a._v("小伟在日记里默默写下了对小娟的感受, 却迟迟没有勇气给她展示。他们在一起的时候, 他时常对她投去温柔的目光, 但言语间却总是遮掩自己的情感。小娟也察觉到了小伟的变化, 但她也不敢轻易表白。")]),a._v(" "),t("h3",{attrs:{id:"第四章-秘密的表白"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第四章-秘密的表白"}},[a._v("#")]),a._v(" 第四章: 秘密的表白")]),a._v(" "),t("p",[a._v("在一个温暖的春日午后, 小伟鼓起勇气, 在小娟最喜欢的花海中, 将自己的情感告诉了她。小娟惊讶又感动, 她终于鼓起勇气告诉小伟, 她也喜欢他很久了。两人终于坦诚相对, 他们的感情更加深厚。")]),a._v(" "),t("h3",{attrs:{id:"第五章-青涩初恋"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第五章-青涩初恋"}},[a._v("#")]),a._v(" 第五章: 青涩初恋")]),a._v(" "),t("p",[a._v("小伟和小娟的初恋在校园里悄然兴起。他们手牵手, 在校园里散步, 分享着彼此的喜怒哀乐。他们成了同学们眼中的模范情侣, 也成了老师们眼中的可爱学生。初恋的甜蜜让他们陶醉其中, 但也会面临一些稚嫩的矛盾和挑战。")]),a._v(" "),t("h3",{attrs:{id:"第六章-挑战与成长"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第六章-挑战与成长"}},[a._v("#")]),a._v(" 第六章: 挑战与成长")]),a._v(" "),t("p",[a._v("随着时间的推移, 小伟和小娟面临着学业上的考验。他们都渐渐成熟起来, 但也开始面临一些分别的压力。小伟的牙医梦想让他要考虑出国深造的可能, 而小娟也有自己的理想。两人开始慢慢犹豫和纠结, 不知道该如何选择。")]),a._v(" "),t("h3",{attrs:{id:"第七章-距离的考验"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第七章-距离的考验"}},[a._v("#")]),a._v(" 第七章: 距离的考验")]),a._v(" "),t("p",[a._v("最终, 小伟和小娟选择了分别。小伟去了一个国外的医学院, 而小娟则留在国内继续学业。距离让他们开始怀疑这份感情是否可以长久, 但他们也都坚信, 只要心中有对方, 距离并不能阻挡他们的爱。")]),a._v(" "),t("h3",{attrs:{id:"第八章-短暂的分别"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第八章-短暂的分别"}},[a._v("#")]),a._v(" 第八章: 短暂的分别")]),a._v(" "),t("p",[a._v("在异国他乡, 小伟开始了他的学业生涯。虽然他很忙碌, 但他依然每天都会和小娟保持联系。每当他们视频通话时, 小娟总是鼓励他坚持下去, 而小伟也会告诉小娟, 他们一定会在未来再次相聚。")]),a._v(" "),t("h3",{attrs:{id:"第九章-新的朋友"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第九章-新的朋友"}},[a._v("#")]),a._v(" 第九章: 新的朋友")]),a._v(" "),t("p",[a._v("在国外, 小伟结识了一些新的朋友, 其中有一位性格开朗、善解人意的女孩, 名叫苏雪。苏雪和小伟逐渐成了很好的朋友, 她对小伟的牙医事业也很支持, 常常陪着他度过思念小娟的时光。")]),a._v(" "),t("h3",{attrs:{id:"第十章-意外的邂逅"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十章-意外的邂逅"}},[a._v("#")]),a._v(" 第十章: 意外的邂逅")]),a._v(" "),t("p",[a._v("在一个偶然的聚会中, 小伟意外地遇到了小娟的堂弟, 名叫小飞。小飞和小娟感情很好, 他向小伟透露了小娟最近的近况。原来, 小娟也在经历着一些挑战和变化, 但她对小伟的思念从未减退。")]),a._v(" "),t("h3",{attrs:{id:"第十一章-思念的夜晚"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十一章-思念的夜晚"}},[a._v("#")]),a._v(" 第十一章: 思念的夜晚")]),a._v(" "),t("p",[a._v("得知小娟的情况后, 小伟更加思念她。每当夜深人静, 他会一个人躺在床上, 回想起和小娟一起度过的美好时光。在他心中, 小娟永远是最特别的存在。同时, 小伟开始认真思考他们的未来, 他不知道他们之间会有怎样的结局, 但他决定要为了他们的爱而努力。")]),a._v(" "),t("h3",{attrs:{id:"第十二章-苏雪的心结"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十二章-苏雪的心结"}},[a._v("#")]),a._v(" 第十二章: 苏雪的心结")]),a._v(" "),t("p",[a._v("苏雪逐渐发现自己对小伟有着更复杂的情感。她看到小伟坚持不懈地思念着小娟, 也看到小娟在他心中的特殊地位。她明白, 自己喜欢的人已经心里有了别人。虽然苏雪为自己的情感感到矛盾, 但她也不愿伤害小伟的心。")]),a._v(" "),t("h3",{attrs:{id:"第十三章-选择与放手"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十三章-选择与放手"}},[a._v("#")]),a._v(" 第十三章: 选择与放手")]),a._v(" "),t("p",[a._v("在一个星期天的下午, 苏雪找到小伟, 坦白地向他表白自己的感情。小伟听后显得有些犹豫, 他不愿意伤害苏雪的心, 但他也不能对她有所欺瞒。他坦诚地告诉苏雪, 他心里一直有一个人, 而那个人是小娟。虽然苏雪心痛, 但她也理解, 于是她选择了放手。")]),a._v(" "),t("h3",{attrs:{id:"第十四章-重逢的喜悦"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十四章-重逢的喜悦"}},[a._v("#")]),a._v(" 第十四章: 重逢的喜悦")]),a._v(" "),t("p",[a._v("经过了一段时间的分别, 小伟终于回到了家乡。当小娟得知他要回来时, 内心充满了喜悦。他们在火车站的候车室重逢, 小娟含情脉脉地看着小伟, 而小伟也拉着小娟的手, 告诉她他一直在思念着她。两人紧紧拥抱在一起, 那一刻, 所有的犹豫和分别都变得微不足道。")]),a._v(" "),t("h3",{attrs:{id:"第十五章-爱的坚持"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十五章-爱的坚持"}},[a._v("#")]),a._v(" 第十五章: 爱的坚持")]),a._v(" "),t("p",[a._v("小伟和小娟重新走到了一起, 他们决定要一直坚守这份爱。他们明白, 爱情不是一帆风顺的, 但只要心中有对方, 他们就能共同克服所有的困难。小伟也向小娟保证, 无论将来会面临什么样的选择, 他都会坚持他们的爱, 无怨无悔地陪在她身边。")]),a._v(" "),t("h3",{attrs:{id:"第十六章-牙医的助力"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十六章-牙医的助力"}},[a._v("#")]),a._v(" 第十六章: 牙医的助力")]),a._v(" "),t("p",[a._v("小伟在牙医事业上越发有所成就, 他的名气逐渐传遍了整个城市。擅长牙医的他, 也为小娟提供了许多帮助。小娟因为工作忙碌, 常常疏于照顾自己的牙齿。每当她有口腔问题时, 小伟总是第一时间出现在她身边, 给予专业的建议和治疗。")]),a._v(" "),t("h3",{attrs:{id:"第十七章-幸福的时光"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十七章-幸福的时光"}},[a._v("#")]),a._v(" 第十七章: 幸福的时光")]),a._v(" "),t("p",[a._v("小伟和小娟在一起的日子里, 每一刻都充满了幸福。他们一起看电影, 一起逛街, 一起分享生活中的点滴喜悦。他们的爱情越发坚定, 彼此也变得更加默契。在这段幸福的时光里, 他们渐渐成为了对方生命中不可或缺的一部分。")]),a._v(" "),t("h3",{attrs:{id:"第十八章-职业与家庭的平衡"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十八章-职业与家庭的平衡"}},[a._v("#")]),a._v(" 第十八章: 职业与家庭的平衡")]),a._v(" "),t("p",[a._v("随着家庭的扩大, 小伟开始面临职业和家庭的平衡问题。作为一个牙医, 他的工作很繁忙, 但他也希望能够陪伴在家人身边。小娟理解丈夫的辛苦, 她支持他在事业上取得更大的成就, 同时也希望他能够更多地参与到家庭中来。")]),a._v(" "),t("p",[a._v("小伟决定要寻找一种平衡, 他安排自己的工作时间, 尽量不让工作影响到与小娟和孩子相处的时间。每当他在诊所忙碌, 他都会通过电话或视频与家人保持联系, 分享他们生活中的点滴。")]),a._v(" "),t("h3",{attrs:{id:"第十九章-挑战与困惑"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第十九章-挑战与困惑"}},[a._v("#")]),a._v(" 第十九章: 挑战与困惑")]),a._v(" "),t("p",[a._v("在职业和家庭的平衡中, 小伟感到有些困惑。他担心自己不能兼顾好家庭和事业, 担心自己会辜负了小娟和孩子。然而, 在小娟的鼓励下, 他坚定地告诉自己, 他可以做到。他要用自己的努力和爱来守护他们的家。")]),a._v(" "),t("p",[a._v("小娟也面临着自己职业和家庭的挑战。虽然她热爱摄影, 但时常为了家庭放弃了一些工作机会。她开始思考如何在追求梦想的同时, 也更好地照顾家人。两人一同面对着这个人生的新阶段, 共同寻找着解决的办法。")]),a._v(" "),t("h3",{attrs:{id:"第二十章-成长的友情"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十章-成长的友情"}},[a._v("#")]),a._v(" 第二十章: 成长的友情")]),a._v(" "),t("p",[a._v("在工作中, 小伟结识了许多优秀的医生和同事。其中, 有一位名叫张林的医生, 成为了小伟的好朋友。张林是一位非常聪明和努力的医生, 他对小伟的牙医事业表示了很大的钦佩, 两人成为了知心朋友, 一起分享着成长的喜悦和困难。")]),a._v(" "),t("p",[a._v("张林也和小伟一样, 面临着职业和家庭的平衡问题。他是一位出色的医生, 但他也希望能够更多地陪伴家人。在小伟和小娟的影响下, 张林开始尝试调整工作时间, 更多地参与到家庭中来。他们一起交流着在职业和家庭之间找到平衡的经验, 成为了彼此的支持和鼓励。")]),a._v(" "),t("h3",{attrs:{id:"第二十一章-家庭的温暖"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十一章-家庭的温暖"}},[a._v("#")]),a._v(" 第二十一章: 家庭的温暖")]),a._v(" "),t("p",[a._v("新生命的降临, 让小伟和小娟的家庭充满了更多的温暖和喜悦。他们一起照顾着孩子, 分享着每一个成长的瞬间。小伟成为了一个贴心的父亲, 他用温柔的手指为孩子轻轻擦拭泪水, 用悉心的关怀陪伴着孩子成长。")]),a._v(" "),t("h3",{attrs:{id:"第二十二章-职业与家庭的平衡"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十二章-职业与家庭的平衡"}},[a._v("#")]),a._v(" 第二十二章: 职业与家庭的平衡")]),a._v(" "),t("p",[a._v("随着家庭的扩大, 小伟开始面临职业和家庭的平衡问题。作为一个牙医, 他的工作很繁忙, 但他也希望能够陪伴在家人身边。小娟理解丈夫的辛苦, 她支持他在事业上取得更大的成就, 同时也希望他能够更多地参与到家庭中来。")]),a._v(" "),t("h3",{attrs:{id:"第二十三章-挑战与困惑"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十三章-挑战与困惑"}},[a._v("#")]),a._v(" 第二十三章: 挑战与困惑")]),a._v(" "),t("p",[a._v("在事业和家庭之间, 小伟感到有些困惑。他担心自己不能兼顾好家庭和事业, 担心自己会辜负了小娟和孩子。然而, 在小娟的鼓励下, 他坚定地告诉自己, 他可以做到。他要用自己的努力和爱来守护他们的家。")]),a._v(" "),t("h3",{attrs:{id:"第二十四章-成长的友情"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十四章-成长的友情"}},[a._v("#")]),a._v(" 第二十四章: 成长的友情")]),a._v(" "),t("p",[a._v("在工作中, 小伟结识了许多优秀的医生和同事。其中, 有一位名叫张林的医生, 成为了小伟的好朋友。张林是一位非常聪明和努力的医生, 他对小伟的牙医事业表示了很大的钦佩, 两人成为了知心朋友, 一起分享着成长的喜悦和困难。")]),a._v(" "),t("h3",{attrs:{id:"第二十五章-家族的团聚"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十五章-家族的团聚"}},[a._v("#")]),a._v(" 第二十五章: 家族的团聚")]),a._v(" "),t("p",[a._v("小伟的家人听说他已经结婚并有了孩子, 都非常开心, 希望能尽早见到小娟和孩子。于是, 他们一起计划着一个家族团聚的活动。在一个温馨的周末, 小伟和小娟带着孩子回到家乡, 与家人一起度过了快乐的时光。")]),a._v(" "),t("h3",{attrs:{id:"第二十六章-新的起点"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十六章-新的起点"}},[a._v("#")]),a._v(" 第二十六章: 新的起点")]),a._v(" "),t("p",[a._v("在家人和朋友的祝福下, 小伟和小娟决定要重新规划自己的未来。小娟放弃了原本的工作, 开始学习摄影。她拍摄了许多感人至深的照片, 用镜头记录了家人和朋友的美好瞬间。而小伟也决定要扩大自己的诊所, 为更多的人带去健康的笑容。")]),a._v(" "),t("h3",{attrs:{id:"第二十七章-梦想成真"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十七章-梦想成真"}},[a._v("#")]),a._v(" 第二十七章: 梦想成真")]),a._v(" "),t("p",[a._v("随着时间的推移, 小伟和小娟都实现了自己的梦想。小娟的摄影作品被发表在许多杂志和画廊中, 她成为了一名备受赞誉的摄影师。而小伟的诊所也越来越繁忙, 他的牙医事业蒸蒸日上。他们的努力得到了回报, 也让他们的生活更加丰富多彩。")]),a._v(" "),t("h3",{attrs:{id:"第二十八章-爱的传承"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十八章-爱的传承"}},[a._v("#")]),a._v(" 第二十八章: 爱的传承")]),a._v(" "),t("p",[a._v("小伟和小娟的孩子渐渐长大, 他们将父母的爱传承下去。他们教导孩子善良、坚强和勇敢, 让他们学会珍惜家人和友谊。小伟和小娟也经常带着孩子一起旅行, 让他们了解更广阔的世界。")]),a._v(" "),t("h3",{attrs:{id:"第二十九章-美好的未来"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第二十九章-美好的未来"}},[a._v("#")]),a._v(" 第二十九章: 美好的未来")]),a._v(" "),t("p",[a._v("小伟和小娟一起迎接着未来的每一天。他们的爱情依然充满着甜蜜和温暖, 他们一直相信着, 只要心中有爱, 他们的未来会更美好。在家人和朋友的陪伴下, 他们共同创造了一个温馨幸福的家庭。")]),a._v(" "),t("h3",{attrs:{id:"第三十章-永恒的爱"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#第三十章-永恒的爱"}},[a._v("#")]),a._v(" 第三十章: 永恒的爱")]),a._v(" "),t("p",[a._v("岁月如歌, 小伟和小娟的故事还在继续。他们的爱情虽然经历了波折, 但它却更加坚定。他们一直相互扶持着, 共同创造着属于他们的美好未来。小伟和小娟的故事不仅是一段浪漫的爱情, 更是一种真挚而永恒的情感, 将在岁月中永远闪耀。")])])}),[],!1,null,null,null);t.default=v.exports}}]);
\ No newline at end of file
diff --git a/assets/js/154.1b84acfa.js b/assets/js/154.1b84acfa.js
new file mode 100644
index 00000000000..5a26ba4e1f6
--- /dev/null
+++ b/assets/js/154.1b84acfa.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[154],{470:function(s,t,n){"use strict";n.r(t);var a=n(4),e=Object(a.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("div",{staticClass:"language-gradle line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-gradle"}},[t("code",[s._v("String ANDROID_PUBLIC_MAVEN_URL "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'xxx'")]),s._v("\nString MAVEN_USERNAME "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'xxx'")]),s._v("\nString MAVEN_PASSWORD "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'xxx'")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("def")]),s._v(" setMavenCredentials "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" MavenArtifactRepository repo "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAllowInsecureProtocol")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("credentials "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n username "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" MAVEN_USERNAME\n password "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" MAVEN_PASSWORD\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("authentication "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("basic")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("BasicAuthentication"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("def")]),s._v(" String "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("fixedUrl")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("String url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n url "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("trim")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("endsWith")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token interpolation-string"}},[t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"/"')])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n url "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("substring")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("length")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n return url\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("def")]),s._v(" setAndroidPublicMaven "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" RepositoryHandler repositoryHandler "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n repositoryHandler"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("maven "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" MavenArtifactRepository repo "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("url")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ANDROID_PUBLIC_MAVEN_URL"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setMavenCredentials")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n repositoryHandler"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("all "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" ArtifactRepository repo "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("class"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("name "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'org.gradle.plugin.use.internal.PluginArtifactRepository'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n try "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n repo "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("delegate\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" catch "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("Throwable ignored"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("repo instanceof "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("MavenArtifactRepository")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n URI uri "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("url\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("uri "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" null"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n String url "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" uri"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("normalize")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("toString")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("fixedUrl")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("url"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("fixedUrl")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ANDROID_PUBLIC_MAVEN_URL"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setMavenCredentials")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("repo"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\ngradle"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("beforeSettings "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" Settings settings "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n settings"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("pluginManagement "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" pluginManagementSpec "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("pluginManagementSpec"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 设置构建脚本的 buildscript 部分的仓库")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("settings"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("buildscript"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n try "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 用于配置依赖解析管理")]),s._v("\n settings"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("dependencyResolutionManagement "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" dependencyManagementSpec "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("dependencyManagementSpec"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("catch")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("Exception e"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 低版本gradle不支持dependencyResolutionManagement")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\ngradle"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("beforeProject "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" Project "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("project")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("->")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("project")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("buildscript"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAndroidPublicMaven")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("project")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("repositories")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br"),t("span",{staticClass:"line-number"},[s._v("39")]),t("br"),t("span",{staticClass:"line-number"},[s._v("40")]),t("br"),t("span",{staticClass:"line-number"},[s._v("41")]),t("br"),t("span",{staticClass:"line-number"},[s._v("42")]),t("br"),t("span",{staticClass:"line-number"},[s._v("43")]),t("br"),t("span",{staticClass:"line-number"},[s._v("44")]),t("br"),t("span",{staticClass:"line-number"},[s._v("45")]),t("br"),t("span",{staticClass:"line-number"},[s._v("46")]),t("br"),t("span",{staticClass:"line-number"},[s._v("47")]),t("br"),t("span",{staticClass:"line-number"},[s._v("48")]),t("br"),t("span",{staticClass:"line-number"},[s._v("49")]),t("br"),t("span",{staticClass:"line-number"},[s._v("50")]),t("br"),t("span",{staticClass:"line-number"},[s._v("51")]),t("br"),t("span",{staticClass:"line-number"},[s._v("52")]),t("br"),t("span",{staticClass:"line-number"},[s._v("53")]),t("br"),t("span",{staticClass:"line-number"},[s._v("54")]),t("br"),t("span",{staticClass:"line-number"},[s._v("55")]),t("br"),t("span",{staticClass:"line-number"},[s._v("56")]),t("br"),t("span",{staticClass:"line-number"},[s._v("57")]),t("br"),t("span",{staticClass:"line-number"},[s._v("58")]),t("br"),t("span",{staticClass:"line-number"},[s._v("59")]),t("br"),t("span",{staticClass:"line-number"},[s._v("60")]),t("br"),t("span",{staticClass:"line-number"},[s._v("61")]),t("br"),t("span",{staticClass:"line-number"},[s._v("62")]),t("br"),t("span",{staticClass:"line-number"},[s._v("63")]),t("br"),t("span",{staticClass:"line-number"},[s._v("64")]),t("br"),t("span",{staticClass:"line-number"},[s._v("65")]),t("br"),t("span",{staticClass:"line-number"},[s._v("66")]),t("br"),t("span",{staticClass:"line-number"},[s._v("67")]),t("br"),t("span",{staticClass:"line-number"},[s._v("68")]),t("br"),t("span",{staticClass:"line-number"},[s._v("69")]),t("br")])])])}),[],!1,null,null,null);t.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/155.98db01de.js b/assets/js/155.98db01de.js
new file mode 100644
index 00000000000..a48befb1530
--- /dev/null
+++ b/assets/js/155.98db01de.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[155],{471:function(e,r,t){"use strict";t.r(r);var o=t(4),n=Object(o.a)({},(function(){var e=this,r=e._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("blockquote",[r("p",[e._v("Android 概述: 对相关知识进行归纳整理")])]),e._v(" "),r("h2",{attrs:{id:"link"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[e._v("#")]),e._v(" link")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://developer.android.com",target:"_blank",rel:"noopener noreferrer"}},[e._v("Android developer"),r("OutboundLink")],1),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://developer.android.com/samples?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[e._v("sample"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://developer.android.com/design/ui/mobile/samples",target:"_blank",rel:"noopener noreferrer"}},[e._v("ui-mobile-samples"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://source.android.com/docs/core?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[e._v("Android 系统核心主题*"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://m3.material.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Material 3"),r("OutboundLink")],1)]),e._v(" "),r("li",[e._v("jetpack\n"),r("ul",[r("li",[r("a",{attrs:{href:"https://developer.android.com/jetpack/compose",target:"_blank",rel:"noopener noreferrer"}},[e._v("jetpack-compose"),r("OutboundLink")],1),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://developer.android.com/codelabs/jetpack-compose-basics",target:"_blank",rel:"noopener noreferrer"}},[e._v("jetpack-compose-basics"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/android/compose-samples.git",target:"_blank",rel:"noopener noreferrer"}},[e._v("sample"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"https://developer.android.com/courses/pathways/compose?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[e._v("courses"),r("OutboundLink")],1)])])])])])])]),e._v(" "),r("li",[r("a",{attrs:{href:"https://www.android.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("android 官网"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("a",{attrs:{href:"http://androidxref.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("androidxref"),r("OutboundLink")],1),e._v(" 源代码查看网站, 网站暂停更新了, 只有 2011-2018 年的代码收录")]),e._v(" "),r("li",[r("a",{attrs:{href:"https://cs.android.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Android Code Search"),r("OutboundLink")],1)]),e._v(" "),r("li",[r("RouterLink",{attrs:{to:"/pages/cf019c/"}},[e._v("Kotlin")])],1)]),e._v(" "),r("h3",{attrs:{id:"厂商链接"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#厂商链接"}},[e._v("#")]),e._v(" 厂商链接")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://club.honor.com/cn/",target:"_blank",rel:"noopener noreferrer"}},[e._v("荣耀俱乐部"),r("OutboundLink")],1),e._v(": 查看更新内容")])]),e._v(" "),r("h2",{attrs:{id:"工具"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#工具"}},[e._v("#")]),e._v(" 工具")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://perfetto.dev/docs/quickstart/android-tracing",target:"_blank",rel:"noopener noreferrer"}},[e._v("Perfetto"),r("OutboundLink")],1),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://perfetto.dev/docs/visualization/perfetto-ui",target:"_blank",rel:"noopener noreferrer"}},[e._v("perfetto-ui"),r("OutboundLink")],1)])])]),e._v(" "),r("li",[r("a",{attrs:{href:"https://www.androiddevtools.cn/",target:"_blank",rel:"noopener noreferrer"}},[e._v("androiddevtools"),r("OutboundLink")],1)])]),e._v(" "),r("h2",{attrs:{id:"to-read"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#to-read"}},[e._v("#")]),e._v(" to read")]),e._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://developer.android.com/guide/topics/manifest/activity-element#lmode",target:"_blank",rel:"noopener noreferrer"}},[e._v("https://developer.android.com/guide/topics/manifest/activity-element#lmode"),r("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/156.54008d5a.js b/assets/js/156.54008d5a.js
new file mode 100644
index 00000000000..ba77f7ab31e
--- /dev/null
+++ b/assets/js/156.54008d5a.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[156],{472:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/157.0e1101f3.js b/assets/js/157.0e1101f3.js
new file mode 100644
index 00000000000..44ae8c0350e
--- /dev/null
+++ b/assets/js/157.0e1101f3.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[157],{473:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/158.a4e9b613.js b/assets/js/158.a4e9b613.js
new file mode 100644
index 00000000000..e92e7b710c7
--- /dev/null
+++ b/assets/js/158.a4e9b613.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[158],{474:function(t,r,n){"use strict";n.r(r);var s=n(4),e=Object(s.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"链接"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[this._v("#")]),this._v(" 链接")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://groovy-lang.org/documentation.html",target:"_blank",rel:"noopener noreferrer"}},[this._v("groovy-lang"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/159.4550a232.js b/assets/js/159.4550a232.js
new file mode 100644
index 00000000000..1081fbdff98
--- /dev/null
+++ b/assets/js/159.4550a232.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[159],{475:function(t,e,r){"use strict";r.r(e);var n=r(4),o=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"classes-objects"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#classes-objects"}},[t._v("#")]),t._v(" classes & objects")]),t._v(" "),e("ul",[e("li",[t._v("Delegation")]),t._v(" "),e("li",[e("a",{attrs:{href:"https://kotlinlang.org/docs/delegated-properties.htm",target:"_blank",rel:"noopener noreferrer"}},[t._v("Delegate properties"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://kotlinlang.org/docs/destructuring-declarations.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Destructuring declarations"),e("OutboundLink")],1),t._v(" "),e("ul",[e("li",[t._v("return two values from a function")])])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://kotlinlang.org/docs/reflection.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Reflection"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"链接"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[t._v("#")]),t._v(" 链接")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://kotlinlang.org/",target:"_blank",rel:"noopener noreferrer"}},[t._v("kotlinlang"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://developer.android.com/kotlin?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[t._v("Kotlin.android"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/16.32123a80.js b/assets/js/16.32123a80.js
new file mode 100644
index 00000000000..22c3bb64607
--- /dev/null
+++ b/assets/js/16.32123a80.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{335:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/160.8a1ec2c2.js b/assets/js/160.8a1ec2c2.js
new file mode 100644
index 00000000000..2825198be1a
--- /dev/null
+++ b/assets/js/160.8a1ec2c2.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[160],{476:function(t,a,s){"use strict";s.r(a);var r=s(4),e=Object(r.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"入门"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#入门"}},[t._v("#")]),t._v(" 入门")]),t._v(" "),a("h3",{attrs:{id:"协程-vs-回调"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#协程-vs-回调"}},[t._v("#")]),t._v(" 协程 vs 回调")]),t._v(" "),a("p",[t._v("回调是一种很好的模式, 但也存在缺点。过多使用回调的代码可能会变得难以读取和推演。此外, 回调也不允许使用某些语言功能, 例如异常。")]),t._v(" "),a("p",[t._v("Kotlin 协程使您能够将基于回调的代码转换为顺序代码。顺序编写的代码通常更易于阅读, 甚至可以使用"),a("strong",[t._v("异常等语言功能")]),t._v("。")]),t._v(" "),a("p",[t._v("最后, 两者所做的事情完全相同: 等待长时间运行的任务获得结果, 然后继续执行。不过, 两者的代码看起来却截然不同。")]),t._v(" "),a("h3",{attrs:{id:"coroutinescope"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#coroutinescope"}},[t._v("#")]),t._v(" CoroutineScope")]),t._v(" "),a("p",[t._v("Kotlin 中, 所有协程都在 CoroutineScope 中运行。作用域在其整个作业期间会控制协程的生命周期。如果取消某个作用域的作业, 则该作用域内启动的所有协程也将取消")]),t._v(" "),a("h3",{attrs:{id:"调度程序"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#调度程序"}},[t._v("#")]),t._v(" 调度程序")]),t._v(" "),a("p",[t._v("Kotlin 协程提供三个调度程序: Main、IO 和 Default。")]),t._v(" "),a("ul",[a("li",[t._v("Main 调度程序用于在 Android 主线程上运行协")]),t._v(" "),a("li",[t._v("IO 调度程序针对 IO 工作进行了优化, 例如从网络或磁盘读取内容")]),t._v(" "),a("li",[t._v("Default 调度程序则针对 CPU 密集型任务进行了优化。")])]),t._v(" "),a("h3",{attrs:{id:"withcontext"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#withcontext"}},[t._v("#")]),t._v(" "),a("a",{attrs:{href:"https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/with-context.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("WithContext"),a("OutboundLink")],1),t._v(":")]),t._v(" "),a("p",[t._v("在任何调度程序之间切换时, 协程会使用 withContext")]),t._v(" "),a("h3",{attrs:{id:"continuation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#continuation"}},[t._v("#")]),t._v(" Continuation")]),t._v(" "),a("h2",{attrs:{id:"其他"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#其他"}},[t._v("#")]),t._v(" 其他")]),t._v(" "),a("h3",{attrs:{id:"suspend"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#suspend"}},[t._v("#")]),t._v(" suspend")]),t._v(" "),a("p",[t._v("关键字 suspend 是 Kotlin 将函数(即函数类型)标记为可供协程使用的方式。当协程调用标记为 suspend 的函数时, 它不会像常规函数调用一样在函数返回之前进行阻塞, 而是挂起执行, 直到结果就绪为止, 然后从上次停止的位置恢复并使用返回的结果。当它挂起并等待结果时, 它会取消阻塞正在运行它的线程, 以便其他函数或协程可以运行。")])])}),[],!1,null,null,null);a.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/161.13b78023.js b/assets/js/161.13b78023.js
new file mode 100644
index 00000000000..a9adefa6361
--- /dev/null
+++ b/assets/js/161.13b78023.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[161],{477:function(t,r,s){"use strict";s.r(r);var e=s(4),n=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"任务管理"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#任务管理"}},[this._v("#")]),this._v(" 任务管理")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/BoltsFramework/Bolts-Android",target:"_blank",rel:"noopener noreferrer"}},[this._v("Bolts-Android"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/162.a5324662.js b/assets/js/162.a5324662.js
new file mode 100644
index 00000000000..b2648f67ee5
--- /dev/null
+++ b/assets/js/162.a5324662.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[162],{478:function(a,e,r){"use strict";r.r(e);var t=r(4),s=Object(t.a)({},(function(){var a=this,e=a._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[e("h2",{attrs:{id:"为什么-java-7-hashmap-在多线程下会发生死循环"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#为什么-java-7-hashmap-在多线程下会发生死循环"}},[a._v("#")]),a._v(" 为什么 Java 7 HashMap 在多线程下会发生死循环?")]),a._v(" "),e("blockquote",[e("p",[a._v("https://zhengw-tech.com/2019/06/01/java-rehash/")])]),a._v(" "),e("blockquote",[e("p",[a._v("https://blog.csdn.net/qq_27376871/article/details/109630451")])]),a._v(" "),e("p",[a._v('对于 Java 7 及以前的 HashMap, 采用了"链地址法", 即内部结构是: '),e("code",[a._v("数组+链表")]),a._v("。K-V 的 key 经过 Hash 后可能会被分在数组的相同索引下, 形成一条链表。\n当元素不断增多达到阈值时, HashMap 会自动触发扩容("),e("code",[a._v("容量*2")]),a._v('), 此时会对所有的 Key 进行重新分桶 , 即 ReHash。这时如果发生多线程同时 ReHash, 可能会出现一种现象: 针对某个桶, 线程 A 在 ReHash 中途挂起, 线程 B 进来完成了整个 ReHash, 此时 A 继续 ReHash 则会出现"循环链表", 它会导致 ReHash 陷入死循环状态。\n具体原因可参考源码参考 '),e("a",{attrs:{href:"http://androidxref.com/7.0.0_r1/xref/libcore/ojluni/src/main/java/java/util/HashMap.java#resize",target:"_blank",rel:"noopener noreferrer"}},[a._v("Java 7 HashMap#resize"),e("OutboundLink")],1),a._v("\n如果这个死循环出现在主线程, 则会导致 ANR。")]),a._v(" "),e("h2",{attrs:{id:"为什么-java-8-里不再发生死循环"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#为什么-java-8-里不再发生死循环"}},[a._v("#")]),a._v(" 为什么 Java 8 里不再发生死循环?")]),a._v(" "),e("p",[a._v('上述死循环发生的本质原因, 是 ReHash 构造的新链表顺序与原始链表顺序相反, 才导致了"循环链表"的产生。因此, 在 Java 8 里保证了在扩容时, 链表的顺序不会改变即可。源码参考 '),e("a",{attrs:{href:"http://androidxref.com/8.0.0_r4/xref/libcore/ojluni/src/main/java/java/util/HashMap.java#resize",target:"_blank",rel:"noopener noreferrer"}},[a._v("Java 8 HashMap#resize"),e("OutboundLink")],1),a._v('\n另外, Java 8 里的 HashMap 采用了"数组+链表+红黑树"的实现, 当链表长度大于 8 时, 自动转换成红黑树, 可以提高遍历搜索效率')])])}),[],!1,null,null,null);e.default=s.exports}}]);
\ No newline at end of file
diff --git a/assets/js/163.b6deed1b.js b/assets/js/163.b6deed1b.js
new file mode 100644
index 00000000000..74073bb5c7b
--- /dev/null
+++ b/assets/js/163.b6deed1b.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[163],{479:function(t,s,r){"use strict";r.r(s);var i=r(4),n=Object(i.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"热修"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#热修"}},[this._v("#")]),this._v(" 热修")]),this._v(" "),t("ul",[t("li",[this._v("robust: 美团")])])])}),[],!1,null,null,null);s.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/164.37f358c4.js b/assets/js/164.37f358c4.js
new file mode 100644
index 00000000000..c3fa3ad2a14
--- /dev/null
+++ b/assets/js/164.37f358c4.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[164],{480:function(r,a,e){"use strict";e.r(a);var t=e(4),s=Object(t.a)({},(function(){var r=this,a=r._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":r.$parent.slotKey}},[a("blockquote",[a("p",[r._v("建议直接参考链接内容")])]),r._v(" "),a("h2",{attrs:{id:"android-图形组件"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#android-图形组件"}},[r._v("#")]),r._v(" Android 图形组件")]),r._v(" "),a("p",[a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230528_162006_84h22U.jpg",alt:""}})]),r._v(" "),a("h3",{attrs:{id:"surface-and-surfaceholder"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#surface-and-surfaceholder"}},[r._v("#")]),r._v(" Surface and SurfaceHolder")]),r._v(" "),a("blockquote",[a("p",[a("a",{attrs:{href:"https://source.android.com/docs/core/graphics/arch-sh?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[r._v("Surface and SurfaceHolder"),a("OutboundLink")],1)])]),r._v(" "),a("h2",{attrs:{id:"链接"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[r._v("#")]),r._v(" 链接")]),r._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://source.android.com/docs/core/graphics?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[r._v("android-graphics"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=s.exports}}]);
\ No newline at end of file
diff --git a/assets/js/165.d07e458a.js b/assets/js/165.d07e458a.js
new file mode 100644
index 00000000000..d15dcb0697d
--- /dev/null
+++ b/assets/js/165.d07e458a.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[165],{481:function(t,v,a){"use strict";a.r(v);var _=a(4),e=Object(_.a)({},(function(){var t=this,v=t._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[v("h2",{attrs:{id:"runtime-getmemory-与-activitymanager-memoryinfo"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#runtime-getmemory-与-activitymanager-memoryinfo"}},[t._v("#")]),t._v(" Runtime getMemory 与 ActivityManager.MemoryInfo")]),t._v(" "),v("p",[t._v("在 Android 中, 你可以使用不同的 API 来获取设备的内存信息, 其中包括 Runtime 类的 getRuntime()方法和 ActivityManager.MemoryInfo 类。它们各自用于不同的内存信息获取目的, 以下是它们之间的区别:")]),t._v(" "),v("ol",[v("li",[v("code",[t._v("Runtime.getFreeMemory()")]),t._v("、"),v("code",[t._v("Runtime.totalMemory()")]),t._v(" 和 "),v("code",[t._v("Runtime.maxMemory()")]),t._v(":")])]),t._v(" "),v("ul",[v("li",[v("p",[t._v("Runtime 是 Java 标准库的一部分, 而不是 Android 特定的 API。它提供了一种在 Java 虚拟机中获取内存信息的方式")])]),t._v(" "),v("li",[v("p",[v("code",[t._v("Runtime.getRuntime().freeMemory()")]),t._v(" 返回当前可用的内存大小, 它表示 Java 虚拟机中当前空闲的内存")])]),t._v(" "),v("li",[v("p",[v("code",[t._v("Runtime.getRuntime().totalMemory()")]),t._v(" 返回 Java 虚拟机当前已分配的总内存大小")])]),t._v(" "),v("li",[v("p",[v("code",[t._v("Runtime.getRuntime().maxMemory()")]),t._v(" 返回 Java 虚拟机试图使用的最大内存大小")])])]),t._v(" "),v("p",[t._v("这些方法主要用于监测应用在 Java 虚拟机中的内存使用情况, 而不是整个设备的内存信息。在 Android 中, 通常更推荐使用 Android 特定的内存管理 API 来获取设备内存信息")]),t._v(" "),v("ol",{attrs:{start:"2"}},[v("li",[v("code",[t._v("ActivityManager.MemoryInfo")]),t._v(":")])]),t._v(" "),v("ul",[v("li",[t._v("ActivityManager.MemoryInfo 是 Android 的 API, 它提供了关于设备内存的详细信息")]),t._v(" "),v("li",[t._v("通过创建 ActivityManager.MemoryInfo 的实例, 并使用 ActivityManager 的 getMemoryInfo()方法, 你可以获取包括总内存、可用内存、低内存阈值等在内的更多内存信息")]),t._v(" "),v("li",[t._v("这些信息有助于你监测设备上的内存使用情况, 以便更好地管理应用程序的资源, 并在必要时采取措施来释放内存")])]),t._v(" "),v("p",[t._v("总的来说, Runtime 类的方法主要用于监测 Java 虚拟机内存, 而 "),v("code",[t._v("ActivityManager.MemoryInfo")]),t._v(" 用于监测设备上的系统内存。如果你关心应用程序在设备上的内存使用情况, 通常更建议使用 ActivityManager.MemoryInfo 来获取内存信息, 因为它提供了更多关于设备内存状态的详细信息, 有助于更好地优化你的应用程序")]),t._v(" "),v("h2",{attrs:{id:"meminfo"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#meminfo"}},[t._v("#")]),t._v(" meminfo")]),t._v(" "),v("p",[t._v("在 Android 中,可以使用 "),v("code",[t._v("adb shell dumpsys meminfo")]),t._v(" 命令来查看应用的内存使用情况。这些信息包括多个指标,如 "),v("code",[t._v("PSS(Proportional Set Size")]),t._v(")、私有脏页面、私有干净页面、交换 PSS(SwapPSS)等。让我们解析一下这些指标,并解释它们在内存分析中的意义")]),t._v(" "),v("h3",{attrs:{id:"各个字段的含义"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#各个字段的含义"}},[t._v("#")]),t._v(" 各个字段的含义")]),t._v(" "),v("ol",[v("li",[t._v("Pss Total:")])]),t._v(" "),v("ul",[v("li",[t._v("PSS(Proportional Set Size): 反映进程使用的物理内存大小。这是内存的真实使用情况,按比例分配共享内存的部分。比如,如果有两个进程共享 1MB 的内存,每个进程的 PSS 会增加 512KB")])]),t._v(" "),v("ol",{attrs:{start:"2"}},[v("li",[t._v("Private Dirty:")])]),t._v(" "),v("ul",[v("li",[t._v("私有脏页面: 进程独占且已被修改的内存页面。这些页面不能被交换到磁盘(对交换内存的情况来说),并且不能被其他进程共享")])]),t._v(" "),v("ol",{attrs:{start:"3"}},[v("li",[t._v("Private Clean:")])]),t._v(" "),v("ul",[v("li",[t._v("私有干净页面: 进程独占但未被修改的内存页面。这些页面可以被交换到磁盘以释放内存,或者当它们不再需要时,可以简单地丢弃并从原始资源重新读取")])]),t._v(" "),v("ol",{attrs:{start:"4"}},[v("li",[t._v("SwapPss:")])]),t._v(" "),v("blockquote",[v("p",[t._v("理解 SwapPss 的概念涉及对内存管理和交换(swap)机制的理解。在操作系统中,内存(RAM)是有限的资源,而交换空间(swap space)是一种辅助内存管理的机制,当物理内存不足时,系统会将一部分内存页面写到磁盘的交换空间中,从而释放物理内存。")])]),t._v(" "),v("ul",[v("li",[t._v("交换 PSS: 表示已经被交换到磁盘的内存量。类似于 PSS,但它特指已经被写到交换空间(swap)的内存")])]),t._v(" "),v("ol",{attrs:{start:"5"}},[v("li",[t._v("Heap Size:")])]),t._v(" "),v("ul",[v("li",[t._v("堆大小: 进程当前分配的堆内存总大小")])]),t._v(" "),v("ol",{attrs:{start:"6"}},[v("li",[t._v("Heap Alloc:")])]),t._v(" "),v("ul",[v("li",[t._v("堆分配: 已经被进程使用的堆内存量")])]),t._v(" "),v("ol",{attrs:{start:"7"}},[v("li",[t._v("Heap Free:")])]),t._v(" "),v("ul",[v("li",[t._v("堆空闲: 堆内存中未被使用的部分")])]),t._v(" "),v("h3",{attrs:{id:"内存区域解释"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#内存区域解释"}},[t._v("#")]),t._v(" 内存区域解释")]),t._v(" "),v("ol",[v("li",[t._v("Native Heap:")])]),t._v(" "),v("ul",[v("li",[t._v("原生堆,指的是使用 C/C++ 分配的内存。这部分内存通常由应用的本地代码(如通过 JNI 调用的本地库)分配和管理")])]),t._v(" "),v("ol",{attrs:{start:"2"}},[v("li",[t._v("Dalvik Heap:")])]),t._v(" "),v("ul",[v("li",[t._v("Dalvik 堆,指的是应用的 Java 堆内存。这部分内存用于存储 Java 对象,在 ART(Android Runtime)中实际运行")])]),t._v(" "),v("ol",{attrs:{start:"3"}},[v("li",[t._v("Stack:")])]),t._v(" "),v("ul",[v("li",[t._v("栈内存,每个线程有自己的栈,用于存储线程的局部变量、方法调用信息等")])]),t._v(" "),v("ol",{attrs:{start:"4"}},[v("li",[t._v("Ashmem:")])]),t._v(" "),v("ul",[v("li",[t._v("Android 共享内存("),v("code",[t._v("Anonymous Shared Memory")]),t._v("),用于进程间通信(IPC)的一种共享内存机制")])]),t._v(" "),v("ol",{attrs:{start:"5"}},[v("li",[t._v("Gfx dev:")])]),t._v(" "),v("ul",[v("li",[t._v("图形设备内存,指的是 GPU 使用的内存,用于存储图形缓冲区等")])]),t._v(" "),v("ol",{attrs:{start:"6"}},[v("li",[t._v("Other dev:")])]),t._v(" "),v("ul",[v("li",[t._v("其他设备内存,指的是系统中其他设备使用的内存")])]),t._v(" "),v("ol",{attrs:{start:"7"}},[v("li",[v("code",[t._v(".so mmap")]),t._v(":")])]),t._v(" "),v("ul",[v("li",[t._v("映射的共享对象(Shared Object),指的是通过内存映射(mmap)加载的本地库(.so 文件)")])]),t._v(" "),v("ol",{attrs:{start:"8"}},[v("li",[v("code",[t._v(".apk mmap")]),t._v(":")])]),t._v(" "),v("ul",[v("li",[t._v("映射的 APK 文件,指的是通过内存映射加载的 APK 文件内容")])]),t._v(" "),v("ol",{attrs:{start:"9"}},[v("li",[v("code",[t._v(".ttf mmap")]),t._v(":")])]),t._v(" "),v("ul",[v("li",[t._v("映射的字体文件(TrueType Font),指的是通过内存映射加载的字体文件")])]),t._v(" "),v("ol",{attrs:{start:"10"}},[v("li",[v("code",[t._v(".dex mmap")]),t._v(":")])]),t._v(" "),v("ul",[v("li",[t._v("映射的 DEX 文件,指的是通过内存映射加载的 Dalvik 字节码文件(.dex 文件)")])]),t._v(" "),v("ol",{attrs:{start:"11"}},[v("li",[v("code",[t._v(".oat mmap")]),t._v(":")])]),t._v(" "),v("ul",[v("li",[t._v("映射的 OAT 文件,指的是通过内存映射加载的编译后的 ART 字节码文件(.oat 文件)")])]),t._v(" "),v("ol",{attrs:{start:"12"}},[v("li",[v("code",[t._v(".art mmap")]),t._v(":")])]),t._v(" "),v("ul",[v("li",[t._v("映射的 ART 文件,指的是通过内存映射加载的 ART 运行时使用的文件")])]),t._v(" "),v("ol",{attrs:{start:"13"}},[v("li",[t._v("Other mmap:")])]),t._v(" "),v("ul",[v("li",[t._v("其他内存映射,指的是通过内存映射加载的其他文件")])]),t._v(" "),v("ol",{attrs:{start:"14"}},[v("li",[t._v("EGL mtrack:")])]),t._v(" "),v("ul",[v("li",[t._v("EGL 内存跟踪,指的是与 EGL(嵌入式图形库)相关的内存")])]),t._v(" "),v("ol",{attrs:{start:"15"}},[v("li",[t._v("GL mtrack:")])]),t._v(" "),v("ul",[v("li",[t._v("OpenGL 内存跟踪,指的是与 OpenGL 相关的内存")])]),t._v(" "),v("ol",{attrs:{start:"16"}},[v("li",[t._v("Unknown:")])]),t._v(" "),v("ul",[v("li",[t._v("未知内存,指的是无法分类的内存")])]),t._v(" "),v("ol",{attrs:{start:"17"}},[v("li",[t._v("TOTAL:")])]),t._v(" "),v("ul",[v("li",[t._v("总内存,指的是上述所有内存区域的总和")])])])}),[],!1,null,null,null);v.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/166.fba21e22.js b/assets/js/166.fba21e22.js
new file mode 100644
index 00000000000..858afc95ba7
--- /dev/null
+++ b/assets/js/166.fba21e22.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[166],{482:function(t,r,s){"use strict";s.r(r);var e=s(4),n=Object(e.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("p",[t("img",{attrs:{src:"https://raw.githubusercontent.com/jacky1234/picArchieve/master/uPic/9ybw5i.jpg",alt:"大纲"}})]),this._v(" "),t("h2",{attrs:{id:"参考"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#参考"}},[this._v("#")]),this._v(" 参考")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://juejin.cn/post/6844903972587716621",target:"_blank",rel:"noopener noreferrer"}},[this._v("深入探索Android稳定性优化"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/167.f6bb79e8.js b/assets/js/167.f6bb79e8.js
new file mode 100644
index 00000000000..2a27f41c73a
--- /dev/null
+++ b/assets/js/167.f6bb79e8.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[167],{483:function(t,r,a){"use strict";a.r(r);var e=a(4),s=Object(e.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h2",{attrs:{id:"拆分"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#拆分"}},[t._v("#")]),t._v(" 拆分")]),t._v(" "),r("h3",{attrs:{id:"性能工具"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#性能工具"}},[t._v("#")]),t._v(" 性能工具")]),t._v(" "),r("ul",[r("li",[t._v("perfetto")]),t._v(" "),r("li",[t._v("frida: 运行时插桩工具")]),t._v(" "),r("li",[t._v("trace 工具: trace 工具以 ASM 插桩为基础, 结合 Perfetto 相关能力, 做到可视化和自动化分析")])]),t._v(" "),r("p",[r("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230926_164338_iWmrVz.png",alt:""}})]),t._v(" "),r("h3",{attrs:{id:"高性能组件"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#高性能组件"}},[t._v("#")]),t._v(" 高性能组件")]),t._v(" "),r("ul",[r("li",[t._v("sharedPreference")]),t._v(" "),r("li",[t._v("锁: trace 分析")])]),t._v(" "),r("h3",{attrs:{id:"智能调度"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#智能调度"}},[t._v("#")]),t._v(" 智能调度")]),t._v(" "),r("p",[r("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230926_164246_xYWEdU.png",alt:""}})]),t._v(" "),r("p",[t._v("调度框架的核心为智能调度, 输入有两部分, 主要是任务和信息采集:")]),t._v(" "),r("ul",[r("li",[r("strong",[t._v("任务")]),t._v(": 业务可将初始化、预加载任务封装成 Task, 注册至任务管理器中, 任务管理器可对任务进行识别并表示, 比如所属业务、依赖业务等, 对任务执行情况做监控;")]),t._v(" "),r("li",[r("strong",[t._v("信息采集")]),t._v(": 主要包括\n"),r("ul",[r("li",[t._v("机型画像(高/中/低端机)")]),t._v(" "),r("li",[t._v("行为画像(用户使用业务频次与时长)")]),t._v(" "),r("li",[t._v("场景识别(闪屏场景、端外调起场景、发起搜索场景等)")]),t._v(" "),r("li",[t._v("分级配置(不同机型画像不同的策略配置)。")])])])]),t._v(" "),r("p",[t._v("输出为不同的调度形态, 有个性化调度(不同用户运行时初始化不同业务)、分级体验调度(用户不同配置机型不同效果)、精细化调度(基于场景做调度)、分优先级延时调度(任务延迟调度支持设置优先级, 调整任务顺序)和首页 UI 并行渲染技术(主要指商业闪屏和主页并行渲染), 业务可根据预加载任务执行诉求快速接入调度实现优化。在任务调度中, 会为特殊业务做针对性调度, 赋能业务, 如闪屏和首页并行渲染, 提升商业请求成功率, 进而商业收入。")]),t._v(" "),r("h3",{attrs:{id:"业务优化"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#业务优化"}},[t._v("#")]),t._v(" 业务优化")]),t._v(" "),r("h2",{attrs:{id:"参考"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#参考"}},[t._v("#")]),t._v(" 参考")]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://juejin.cn/post/7134904047080865805",target:"_blank",rel:"noopener noreferrer"}},[t._v("百度 App 低端机优化-启动性能优化(概述篇)"),r("OutboundLink")],1)])])])}),[],!1,null,null,null);r.default=s.exports}}]);
\ No newline at end of file
diff --git a/assets/js/168.d25f1647.js b/assets/js/168.d25f1647.js
new file mode 100644
index 00000000000..0800f9d60d3
--- /dev/null
+++ b/assets/js/168.d25f1647.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[168],{484:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("blockquote",[t("p",[s._v("可用脚本")])]),s._v(" "),t("div",{staticClass:"language-sh line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-sh"}},[t("code",[t("span",{pre:!0,attrs:{class:"token shebang important"}},[s._v("#!/bin/bash")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 设备序列号")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("DEVICE_SERIAL")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"6289503c9807"')]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# Monkey 测试参数")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("PACKAGE_NAME")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('""')]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 待测试应用的包名")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("EVENT_COUNT")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1000")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 事件数量")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("SEED")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("1234")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 随机种子")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token assign-left variable"}},[s._v("OUTPUT_FILE")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"monkey_log.txt"')]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 输出文件名")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 执行 Monkey 测试")]),s._v("\nadb "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-s")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$DEVICE_SERIAL")]),s._v(" shell monkey "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-p")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$PACKAGE_NAME")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("--throttle")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("500")]),s._v(" --ignore-crashes --ignore-timeouts --ignore-security-exceptions --monitor-native-crashes --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-touch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("100")]),s._v(" --pct-motion "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-trackball "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-v")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("-v")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$EVENT_COUNT")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token parameter variable"}},[s._v("--throttle")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("500")]),s._v(" --ignore-crashes --ignore-timeouts --ignore-security-exceptions --kill-process-after-error --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-touch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("100")]),s._v(" --pct-motion "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-trackball "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-anyevent "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-majornav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-syskeys "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-nav "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-appswitch "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-flip "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-pinchzoom "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" --pct-permission "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("0")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$OUTPUT_FILE")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token builtin class-name"}},[s._v("echo")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"Monkey 测试已完成,结果保存在 '),t("span",{pre:!0,attrs:{class:"token variable"}},[s._v("$OUTPUT_FILE")]),s._v(' 中。"')]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br")])])])}),[],!1,null,null,null);t.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/169.a7413dc2.js b/assets/js/169.a7413dc2.js
new file mode 100644
index 00000000000..6321f07de3b
--- /dev/null
+++ b/assets/js/169.a7413dc2.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[169],{485:function(t,s,a){"use strict";a.r(s);var n=a(4),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("blockquote",[s("p",[t._v("Bitmap的内存消耗主要取决于Bitmap的宽度、高度和配置(即像素格式)。跟 ImageView 的宽高没有关系")])]),t._v(" "),s("h2",{attrs:{id:"bitmap-优化"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#bitmap-优化"}},[t._v("#")]),t._v(" bitmap 优化")]),t._v(" "),s("h3",{attrs:{id:"_1-使用适当的bitmap配置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_1-使用适当的bitmap配置"}},[t._v("#")]),t._v(" 1. 使用适当的Bitmap配置")]),t._v(" "),s("p",[t._v("选择适合的Bitmap.Config,例如Bitmap.Config.RGB_565,可以减少内存使用量。这种配置使用2字节来存储每个像素,而Bitmap.Config.ARGB_8888使用4字节。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Options")]),t._v(" options "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Options")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noptions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inPreferredConfig "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("RGB_565")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap")]),t._v(" bitmap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("decodeResource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getResources")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("R")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("drawable"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("image"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br")])]),s("h3",{attrs:{id:"_2-缩放bitmap"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_2-缩放bitmap"}},[t._v("#")]),t._v(" 2. 缩放Bitmap")]),t._v(" "),s("p",[t._v("如果你需要展示的Bitmap尺寸小于原图的尺寸,可以先缩放Bitmap以减少内存使用。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getScaledBitmap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" reqWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" reqHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Options")]),t._v(" options "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Options")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inJustDecodeBounds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("decodeFile")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inSampleSize "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calculateInSampleSize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" reqWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" reqHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inJustDecodeBounds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("decodeFile")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("static")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("calculateInSampleSize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Options")]),t._v(" options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" reqWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" reqHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" height "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outHeight"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" width "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("outWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" inSampleSize "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("height "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" reqHeight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" width "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" reqWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" halfHeight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" height "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" halfWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" width "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("halfHeight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" inSampleSize"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" reqHeight "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("halfWidth "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" inSampleSize"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" reqWidth"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n inSampleSize "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" inSampleSize"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br"),s("span",{staticClass:"line-number"},[t._v("17")]),s("br"),s("span",{staticClass:"line-number"},[t._v("18")]),s("br"),s("span",{staticClass:"line-number"},[t._v("19")]),s("br"),s("span",{staticClass:"line-number"},[t._v("20")]),s("br"),s("span",{staticClass:"line-number"},[t._v("21")]),s("br"),s("span",{staticClass:"line-number"},[t._v("22")]),s("br"),s("span",{staticClass:"line-number"},[t._v("23")]),s("br"),s("span",{staticClass:"line-number"},[t._v("24")]),s("br")])]),s("h3",{attrs:{id:"_3-使用bitmapfactory-options进行解码"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_3-使用bitmapfactory-options进行解码"}},[t._v("#")]),t._v(" 3. 使用BitmapFactory.Options进行解码")]),t._v(" "),s("p",[t._v("通过设置BitmapFactory.Options来控制解码过程中的内存使用。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Options")]),t._v(" options "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Options")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\noptions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inPurgeable "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 允许系统在内存不足时回收该Bitmap的内存")]),t._v("\noptions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("inInputShareable "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 与inPurgeable配合使用")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap")]),t._v(" bitmap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("decodeResource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getResources")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("R")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("drawable"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("image"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br")])]),s("h3",{attrs:{id:"_4-回收bitmap内存"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_4-回收bitmap内存"}},[t._v("#")]),t._v(" 4. 回收Bitmap内存")]),t._v(" "),s("p",[t._v("在不再需要Bitmap时,及时调用bitmap.recycle()方法释放内存。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bitmap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n bitmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("recycle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n bitmap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br")])]),s("h3",{attrs:{id:"_5-使用内存缓存"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_5-使用内存缓存"}},[t._v("#")]),t._v(" 5. 使用内存缓存")]),t._v(" "),s("p",[t._v("使用内存缓存(如LruCache)来缓存Bitmap,从而避免频繁加载和解码。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LruCache")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v(" memoryCache"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("initCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" maxMemory "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Runtime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getRuntime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("maxMemory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("final")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" cacheSize "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" maxMemory "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n memoryCache "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("LruCache")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cacheSize"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[t._v("@Override")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("protected")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("int")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sizeOf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap")]),t._v(" bitmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" bitmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getByteCount")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addBitmapToMemoryCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap")]),t._v(" bitmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBitmapFromMemCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n memoryCache"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("put")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bitmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("public")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getBitmapFromMemCache")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("String")]),t._v(" key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" memoryCache"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br"),s("span",{staticClass:"line-number"},[t._v("17")]),s("br"),s("span",{staticClass:"line-number"},[t._v("18")]),s("br"),s("span",{staticClass:"line-number"},[t._v("19")]),s("br"),s("span",{staticClass:"line-number"},[t._v("20")]),s("br"),s("span",{staticClass:"line-number"},[t._v("21")]),s("br"),s("span",{staticClass:"line-number"},[t._v("22")]),s("br"),s("span",{staticClass:"line-number"},[t._v("23")]),s("br")])]),s("h3",{attrs:{id:"_6-使用硬件加速"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#_6-使用硬件加速"}},[t._v("#")]),t._v(" 6. 使用硬件加速")]),t._v(" "),s("p",[t._v("在Android 8.0 (API level 26)及更高版本中,可以使用硬件位图(Hardware Bitmaps),这些位图存储在GPU内存中,可以减少应用的内存使用。")]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("VERSION")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SDK_INT")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Build"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("VERSION_CODES"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("O")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap")]),t._v(" bitmap "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("BitmapFactory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("decodeResource")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getResources")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("R")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("drawable"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("image"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n bitmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setConfig")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Bitmap"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("HARDWARE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br")])]),s("h2",{attrs:{id:"link"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[t._v("#")]),t._v(" link")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://juejin.cn/post/6981403029295595534",target:"_blank",rel:"noopener noreferrer"}},[t._v("Android 内存优化之图片优化"),s("OutboundLink")],1)]),t._v(" "),s("li",[s("a",{attrs:{href:"https://mp.weixin.qq.com/s/5H3s4-_bFtM7_2xCqxhFCw",target:"_blank",rel:"noopener noreferrer"}},[t._v("内存大户Bitmap"),s("OutboundLink")],1)])])])}),[],!1,null,null,null);s.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/17.80f38037.js b/assets/js/17.80f38037.js
new file mode 100644
index 00000000000..f61017dfafd
--- /dev/null
+++ b/assets/js/17.80f38037.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{336:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/170.7b106361.js b/assets/js/170.7b106361.js
new file mode 100644
index 00000000000..50e0005aea2
--- /dev/null
+++ b/assets/js/170.7b106361.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[170],{486:function(t,s,a){"use strict";a.r(s);var n=a(4),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("p",[t._v("TODO")]),t._v(" "),s("h2",{attrs:{id:"frida监控"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#frida监控"}},[t._v("#")]),t._v(" frida监控")]),t._v(" "),s("div",{staticClass:"language-js line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("Java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("perform")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" VMRuntime "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("use")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'dalvik.system.VMRuntime'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" runtime "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" VMRuntime"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getRuntime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n VMRuntime"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("newNonMovableArray"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("overload")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'java.lang.Class'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'int'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("implementation")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("cls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("newNonMovableArray")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 判断是否为大对象")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" threshold "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1MB")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" size "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" length "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" Java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("use")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("classSize"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("size "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" threshold"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Allocated large object: Class='")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" cls"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("', Size='")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" size "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("' bytes'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br"),s("span",{staticClass:"line-number"},[t._v("17")]),s("br"),s("span",{staticClass:"line-number"},[t._v("18")]),s("br")])])])}),[],!1,null,null,null);s.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/171.3d8c42ae.js b/assets/js/171.3d8c42ae.js
new file mode 100644
index 00000000000..adbeb031e37
--- /dev/null
+++ b/assets/js/171.3d8c42ae.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[171],{487:function(a,s,t){"use strict";t.r(s);var n=t(4),e=Object(n.a)({},(function(){var a=this,s=a._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[s("RText",{attrs:{text:"anr 堆栈"}}),a._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[a._v("#"),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("00")]),a._v(" pc "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0000000000085e1")]),a._v("c "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("apex"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("com"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("runtime"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("lib64"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("bionic"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("libc"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("so "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("syscall"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("28")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n#"),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("01")]),a._v(" pc "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("000000000028")]),a._v("c158 "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("apex"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("com"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("art"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("lib64"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("libart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("so"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("!")]),a._v("libart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("so "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("offset "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("200000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("art"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("ConditionVariable")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("WaitHoldingLocks")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("art"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Thread")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("148")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n#"),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("02")]),a._v(" pc "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0000000000743148")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("apex"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("com"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("art"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("lib64"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("libart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("so"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("!")]),a._v("libart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("so "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("offset "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("380000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("art"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("GoToRunnable")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("art"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Thread")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("408")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n#"),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("03")]),a._v(" pc "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("0000000000742f")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("7")]),a._v("c "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("apex"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("com"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("art"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("lib64"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("/")]),a._v("libart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("so"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("!")]),a._v("libart"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("so "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("offset "),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("380000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("art"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("JniMethodEnd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("unsigned "),s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("int")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" art"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("::")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Thread")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("+")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("24")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("graphics"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("HardwareRenderer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("nPause")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("HardwareRenderer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("graphics"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("HardwareRenderer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("pause")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("HardwareRenderer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("502")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("view"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("ViewRootImpl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("performTraversals")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("ViewRootImpl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("3884")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("view"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("ViewRootImpl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("doTraversal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("ViewRootImpl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("2837")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("view"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("ViewRootImpl")]),a._v("$"),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("TraversalRunnable")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("run")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("ViewRootImpl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("10520")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("view"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("Choreographer")]),a._v("$"),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("CallbackRecord")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("run")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Choreographer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1623")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("view"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("Choreographer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("doCallbacks")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Choreographer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1141")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("view"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("Choreographer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("doFrame")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Choreographer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1012")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("view"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("Choreographer")]),a._v("$"),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("FrameDisplayEventReceiver")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("run")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Choreographer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("1585")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("os"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("Handler")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("handleCallback")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Handler")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("955")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("os"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("Handler")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("dispatchMessage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Handler")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("102")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("os"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("Looper")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("loopOnce")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Looper")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("206")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("os"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("Looper")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("loop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Looper")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("296")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("app"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("ActivityThread")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("ActivityThread")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("9000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("lang"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("reflect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("Method")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("invoke")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("Method")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("com"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("internal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("os"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("RuntimeInit")]),a._v("$"),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("MethodAndArgsCaller")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("run")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("RuntimeInit")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("569")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n"),s("span",{pre:!0,attrs:{class:"token class-name"}},[s("span",{pre:!0,attrs:{class:"token namespace"}},[a._v("com"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("android"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("internal"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("os"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")])]),a._v("ZygoteInit")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("main")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("ZygoteInit")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),a._v("java"),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),s("span",{pre:!0,attrs:{class:"token number"}},[a._v("976")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),a._v("\n")])]),a._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[a._v("1")]),s("br"),s("span",{staticClass:"line-number"},[a._v("2")]),s("br"),s("span",{staticClass:"line-number"},[a._v("3")]),s("br"),s("span",{staticClass:"line-number"},[a._v("4")]),s("br"),s("span",{staticClass:"line-number"},[a._v("5")]),s("br"),s("span",{staticClass:"line-number"},[a._v("6")]),s("br"),s("span",{staticClass:"line-number"},[a._v("7")]),s("br"),s("span",{staticClass:"line-number"},[a._v("8")]),s("br"),s("span",{staticClass:"line-number"},[a._v("9")]),s("br"),s("span",{staticClass:"line-number"},[a._v("10")]),s("br"),s("span",{staticClass:"line-number"},[a._v("11")]),s("br"),s("span",{staticClass:"line-number"},[a._v("12")]),s("br"),s("span",{staticClass:"line-number"},[a._v("13")]),s("br"),s("span",{staticClass:"line-number"},[a._v("14")]),s("br"),s("span",{staticClass:"line-number"},[a._v("15")]),s("br"),s("span",{staticClass:"line-number"},[a._v("16")]),s("br"),s("span",{staticClass:"line-number"},[a._v("17")]),s("br"),s("span",{staticClass:"line-number"},[a._v("18")]),s("br"),s("span",{staticClass:"line-number"},[a._v("19")]),s("br"),s("span",{staticClass:"line-number"},[a._v("20")]),s("br"),s("span",{staticClass:"line-number"},[a._v("21")]),s("br")])]),s("h2",{attrs:{id:"threadedrenderer-10"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#threadedrenderer-10"}},[a._v("#")]),a._v(" ThreadedRenderer(>10)")]),a._v(" "),s("blockquote",[s("p",[a._v("public final class ThreadedRenderer extends HardwareRenderer {}")])]),a._v(" "),s("p",[a._v("在 Android 10 中将 ThreadedRenderer 改写并继承自 HardwareRenderer 主要是为了改进系统的渲染性能和体验。这个改写带来了一些好处:")]),a._v(" "),s("ul",[s("li",[s("p",[a._v("性能优化: HardwareRenderer 是一个专注于硬件加速渲染的基类, 它提供了更高效的渲染机制。通过将 ThreadedRenderer 继承自 HardwareRenderer, 可以利用硬件加速渲染, 从而提高渲染性能。这对于处理复杂的 UI 和动画效果特别有帮助。")])]),a._v(" "),s("li",[s("p",[a._v("一致性: 通过使用 HardwareRenderer 作为基类, ThreadedRenderer 可以更一致地处理渲染操作, 无论是在软件渲染模式还是硬件加速模式下。这有助于确保应用程序在不同设备上的渲染行为一致, 提供更好的用户体验。")])]),a._v(" "),s("li",[s("p",[a._v("兼容性: 通过基于 HardwareRenderer 构建 ThreadedRenderer, 可以更容易地进行系统升级和改进。这样可以减少代码重复, 提高代码的可维护性, 并简化了系统的渲染架构。")])]),a._v(" "),s("li",[s("p",[a._v("硬件加速支持: 继承自 HardwareRenderer 的 ThreadedRenderer 更容易支持硬件加速, 这意味着应用程序可以更好地利用设备的 GPU 资源, 提高渲染速度和效率。")])])]),a._v(" "),s("p",[a._v("总之, 将 ThreadedRenderer 改写并继承自 HardwareRenderer 主要是为了提高 Android 系统的渲染性能、一致性和兼容性。这有助于改进应用程序的用户体验, 并确保应用程序在不同设备和系统版本上都能正常工作。")]),a._v(" "),s("h2",{attrs:{id:"代码赏析"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#代码赏析"}},[a._v("#")]),a._v(" 代码赏析")]),a._v(" "),s("h3",{attrs:{id:"构造方法"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#构造方法"}},[a._v("#")]),a._v(" 构造方法")]),a._v(" "),s("p",[a._v("下面是 ThreadedRenderer 构造方法的一段内容。解释")]),a._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[a._v("long")]),a._v(" rootNodePtr "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("nCreateRootRenderNode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\nmRootNode "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[a._v("RenderNode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("adopt")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("rootNodePtr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\nmRootNode"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("setClipToBounds")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[a._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\nmIsOpaque "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("!")]),a._v("translucent"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\nmNativeProxy "),s("span",{pre:!0,attrs:{class:"token operator"}},[a._v("=")]),a._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[a._v("nCreateProxy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("(")]),a._v("translucent"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v(" rootNodePtr"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(";")]),a._v("\n")])]),a._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[a._v("1")]),s("br"),s("span",{staticClass:"line-number"},[a._v("2")]),s("br"),s("span",{staticClass:"line-number"},[a._v("3")]),s("br"),s("span",{staticClass:"line-number"},[a._v("4")]),s("br"),s("span",{staticClass:"line-number"},[a._v("5")]),s("br")])]),s("p",[a._v("以下是对代码的解释:")]),a._v(" "),s("ul",[s("li",[s("p",[s("code",[a._v("nCreateRootRenderNode()")]),a._v(": 这个函数用于创建根渲染节点, 返回一个指向根渲染节点的指针, 然后将这个指针存储在 rootNodePtr 变量中。")])]),a._v(" "),s("li",[s("p",[s("code",[a._v("mRootNode = RenderNode.adopt(rootNodePtr)")]),a._v(": 这行代码将根渲染节点指针(rootNodePtr)包装成一个 RenderNode 对象, 并将其赋值给 mRootNode 变量。这个 mRootNode 对象表示应用程序界面的根渲染节点。")])]),a._v(" "),s("li",[s("p",[s("code",[a._v("mRootNode.setClipToBounds(false)")]),a._v(": 这行代码设置根渲染节点的 clipToBounds 属性为 false, 这意味着根渲染节点不会对其内容进行裁剪, 允许内容在渲染中超出根渲染节点的边界。")])]),a._v(" "),s("li",[s("p",[s("code",[a._v("mIsOpaque = !translucent")]),a._v(": 这行代码根据 translucent 变量的值来确定应用程序界面是否是不透明的。如果 translucent 为 true, 则界面是透明的, 因此 mIsOpaque 被设置为 false, 表示不透明。如果 translucent 为 false, 则界面是不透明的, 因此 mIsOpaque 被设置为 true, 表示不透明。")])]),a._v(" "),s("li",[s("p",[s("code",[a._v("mNativeProxy = nCreateProxy(translucent, rootNodePtr)")]),a._v(": 这行代码用于创建渲染代理, 并将其指针存储在 mNativeProxy 变量中。渲染代理负责协调渲染操作, 将渲染请求传递给根渲染节点以及与硬件加速相关的操作。")])])]),a._v(" "),s("p",[a._v("综合起来, 这段代码执行了创建和初始化渲染系统的根渲染节点和渲染代理的操作, 以便开始渲染应用程序界面。这些操作在 Android 渲染流程中非常重要, 因为它们确定了如何绘制应用程序的用户界面。")])],1)}),[],!1,null,null,null);s.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/172.929adbfe.js b/assets/js/172.929adbfe.js
new file mode 100644
index 00000000000..8b066f5fd8e
--- /dev/null
+++ b/assets/js/172.929adbfe.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[172],{488:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 会删减")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AsyncPLog")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("i")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TAG")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"this is a test[1] on release on releasePlayControl"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 不会优化")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AsyncPLog")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("i")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TAG")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"this is a test[2] on release on releasePlayControl"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 会删减")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AbUtil")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("debuggleable")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AsyncPLog")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("i")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TAG")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"this is a test[3] on release on releasePlayControl"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 不会优化")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AbUtil")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("debuggleable2")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AsyncPLog")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("i")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TAG")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"this is a test[4] on release on releasePlayControl"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 会删减")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AbUtil")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("isDebuggable"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AsyncPLog")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("i")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("TAG")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"this is a test[5] on release on releasePlayControl"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br")])]),t("p",[s._v("上述其中 AbUtil 的几个方法定义如下:")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("boolean")]),s._v(" isDebuggable "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// isDebuggable2 未采用 final 进行修饰")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("boolean")]),s._v(" isDebuggable2 "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("boolean")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("debuggleable")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" isDebuggable"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("boolean")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("debuggleable2")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" isDebuggable2"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br")])]),t("p",[s._v("在编译阶段, final 类型内敛,确认不会执行的代码 scope, 会被删除")]),s._v(" "),t("h2",{attrs:{id:"smali-分析"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#smali-分析"}},[s._v("#")]),s._v(" smali 分析")]),s._v(" "),t("p",[s._v("将打包的 release 包采用 apktool 反解成 smali, "),t("code",[s._v("apktool d -r xxx.apk")]),s._v(". 搜索查看相关字符串。 发现指有在明确 "),t("code",[s._v("if(false)")]),s._v(" 中的 scope 代码会主动去处, 其他所有 case 都不会去除")]),s._v(" "),t("h2",{attrs:{id:"思考"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#思考"}},[s._v("#")]),s._v(" 思考")]),s._v(" "),t("p",[s._v("其他在运行时可以确定不需要的如:")]),s._v(" "),t("ul",[t("li",[s._v("logger.d level 的日志")])])])}),[],!1,null,null,null);t.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/173.6d7a124b.js b/assets/js/173.6d7a124b.js
new file mode 100644
index 00000000000..f989d0e4a3b
--- /dev/null
+++ b/assets/js/173.6d7a124b.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[173],{489:function(t,e,a){"use strict";a.r(e);var s=a(4),r=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"proguard-构建产物说明"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#proguard-构建产物说明"}},[t._v("#")]),t._v(" proguard 构建产物说明")]),t._v(" "),e("h3",{attrs:{id:"mapping-txt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#mapping-txt"}},[t._v("#")]),t._v(" mapping.txt")]),t._v(" "),e("p",[t._v("Obfuscation Options,"),e("code",[t._v("-printmapping [filename]")])]),t._v(" "),e("p",[t._v("Specifies to print the mapping from old names to new names for classes and class members that have been renamed. The mapping is printed to the standard output or to the given file. For example, it is required for subsequent incremental obfuscation, or if you ever want to make sense again of obfuscated stack traces. Only applicable when obfuscating.")]),t._v(" "),e("h3",{attrs:{id:"configuration-txt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#configuration-txt"}},[t._v("#")]),t._v(" configuration.txt")]),t._v(" "),e("p",[t._v("General Options: "),e("code",[t._v("-printconfiguration [filename]")])]),t._v(" "),e("p",[t._v("Specifies to write out the entire configuration that has been parsed, with included files and replaced variables. The structure is printed to the standard output or to the given file. This can sometimes be useful to debug configurations, or to convert XML configurations into a more readable format.")]),t._v(" "),e("h3",{attrs:{id:"seeds-txt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeds-txt"}},[t._v("#")]),t._v(" seeds.txt")]),t._v(" "),e("p",[t._v("Keep Options, 可以通过 "),e("code",[t._v("-printseeds [filename]")]),t._v(" 指定输出位置")]),t._v(" "),e("p",[t._v("Specifies to exhaustively list classes and class members matched by the various "),e("code",[t._v("-keep")]),t._v(" options. The list is printed to the standard output or to the given file. The list can be useful to verify if the intended class members are really found, especially if you're using wildcards. For example, you may want to list all the applications or all the applets that you are keeping.")]),t._v(" "),e("h3",{attrs:{id:"usages-txt"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#usages-txt"}},[t._v("#")]),t._v(" usages.txt")]),t._v(" "),e("p",[t._v("可以通过 "),e("code",[t._v("-printusages [filename]")]),t._v(" 指定输出位置")]),t._v(" "),e("p",[t._v("Specifies to list "),e("strong",[t._v("dead code")]),t._v(" of the input class files. The list is printed to the standard output or to the given file. For example, you can list the unused code of an application. Only applicable when shrinking.")]),t._v(" "),e("h2",{attrs:{id:"link"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[t._v("#")]),t._v(" link")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.guardsquare.com/manual/configuration/usage",target:"_blank",rel:"noopener noreferrer"}},[t._v("progurad-usage"),e("OutboundLink")],1),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.guardsquare.com/manual/tools/playground",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://www.guardsquare.com/manual/tools/playground"),e("OutboundLink")],1)])])])])])}),[],!1,null,null,null);e.default=r.exports}}]);
\ No newline at end of file
diff --git a/assets/js/174.31e39190.js b/assets/js/174.31e39190.js
new file mode 100644
index 00000000000..1115e8607b9
--- /dev/null
+++ b/assets/js/174.31e39190.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[174],{490:function(t,e,r){"use strict";r.r(e);var a=r(4),i=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"shrink-code-code-optimize"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#shrink-code-code-optimize"}},[t._v("#")]),t._v(" Shrink code / code optimize")]),t._v(" "),e("h3",{attrs:{id:"两者在r8流程中位置"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#两者在r8流程中位置"}},[t._v("#")]),t._v(" 两者在R8流程中位置")]),t._v(" "),e("p",[e("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20240910_111900_ER3Goc.png",alt:""}})]),t._v(" "),e("h3",{attrs:{id:"共同点"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#共同点"}},[t._v("#")]),t._v(" 共同点")]),t._v(" "),e("p",[t._v("两者都是在编译期间的优化动作,即在静态情况下,能够确认的一些场景,R8就会帮忙直接给优化掉。")]),t._v(" "),e("h3",{attrs:{id:"区别点"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#区别点"}},[t._v("#")]),t._v(" 区别点")]),t._v(" "),e("ul",[e("li",[t._v('shrink可以认为是类、方法、变脸级别的删除。着重注意关键词"删除"\n'),e("ul",[e("li",[t._v("他是在minifyEnabled=true后,就会被默认打开的。")]),t._v(" "),e("li",[t._v("在编译阶段agp会根据程序入口(MainActivity)或者keep的类,会画出一个方法调用栈的图,如果一个类、类成员变量、方法完全不在这个调用图上,那么他们将会被删除掉。")])])]),t._v(" "),e("li",[t._v('optimize主要是指对code重写,他是深入方法内部的一种重新。着重注意关键词"重写"\n'),e("ul",[e("li",[t._v("他是必须是单独配置才能打开的。")]),t._v(" "),e("li",[t._v("举例某个else一定不会进入,就会被删掉;如果一个方法只有在某几个地方调用使用,便会被内联到对方类中。")]),t._v(" "),e("li",[t._v("某些方法太简单,比如只是简单做一个if判断后,就执行一个赋值、打印等,那这个动作会直接被内联到调用方。")])])])]),t._v(" "),e("h2",{attrs:{id:"link"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[t._v("#")]),t._v(" link")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://developer.android.com/build/shrink-code#optimization",target:"_blank",rel:"noopener noreferrer"}},[t._v("Code optimization"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://jakewharton.com/blog/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Jake Wharton的个人博客"),e("OutboundLink")],1),t._v(" 深入字节码理解每项优化的实际原理")])])])}),[],!1,null,null,null);e.default=i.exports}}]);
\ No newline at end of file
diff --git a/assets/js/175.e642d9ee.js b/assets/js/175.e642d9ee.js
new file mode 100644
index 00000000000..650d0518328
--- /dev/null
+++ b/assets/js/175.e642d9ee.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[175],{491:function(t,r,e){"use strict";e.r(r);var n=e(4),a=Object(n.a)({},(function(){var t=this,r=t._self._c;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h2",{attrs:{id:"链接"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[t._v("#")]),t._v(" 链接")]),t._v(" "),r("ul",[r("li",[r("a",{attrs:{href:"https://github.com/Tencent/matrix",target:"_blank",rel:"noopener noreferrer"}},[t._v("matrix"),r("OutboundLink")],1)]),t._v(" "),r("li",[r("a",{attrs:{href:"https://github.com/Tencent/matrix/wiki",target:"_blank",rel:"noopener noreferrer"}},[t._v("wiki"),r("OutboundLink")],1)]),t._v(" "),r("li",[t._v("其他\n"),r("ul",[r("li",[r("a",{attrs:{href:"https://developer.aliyun.com/article/1129193",target:"_blank",rel:"noopener noreferrer"}},[t._v("Matrix 原理分析系列之开篇"),r("OutboundLink")],1)])])])])])}),[],!1,null,null,null);r.default=a.exports}}]);
\ No newline at end of file
diff --git a/assets/js/176.15bb9ab2.js b/assets/js/176.15bb9ab2.js
new file mode 100644
index 00000000000..d65f1d69c24
--- /dev/null
+++ b/assets/js/176.15bb9ab2.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[176],{494:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("blockquote",[t("p",[t("a",{attrs:{href:"https://square.github.io/leakcanary/",target:"_blank",rel:"noopener noreferrer"}},[s._v("leakcanary"),t("OutboundLink")],1),s._v(" is a memory leak detection library for Android. 最新的 leakcanary 已经更新到 3.0 版本了, 有时间可以拜读一下源码")])]),s._v(" "),t("h2",{attrs:{id:"how-leakcanary-works"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#how-leakcanary-works"}},[s._v("#")]),s._v(" How LeakCanary works")]),s._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://square.github.io/leakcanary/fundamentals-how-leakcanary-works/",target:"_blank",rel:"noopener noreferrer"}},[s._v("https://square.github.io/leakcanary/fundamentals-how-leakcanary-works/"),t("OutboundLink")],1)])]),s._v(" "),t("ol",[t("li",[t("p",[s._v("Detecting retained objects")])]),s._v(" "),t("li",[t("p",[s._v("Dumping the heap")])]),s._v(" "),t("li",[t("p",[s._v("Analyzing the heap")]),s._v(" "),t("p",[s._v("LeakCanary parses the "),t("code",[s._v(".hprof")]),s._v(" file using "),t("a",{attrs:{href:"https://square.github.io/leakcanary/shark/",target:"_blank",rel:"noopener noreferrer"}},[s._v("Shark"),t("OutboundLink")],1),s._v(" and locates the retained objects in that heap dump.")])]),s._v(" "),t("li",[t("p",[s._v("Categorizing leaks")])])]),s._v(" "),t("h2",{attrs:{id:"haha-shark"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#haha-shark"}},[s._v("#")]),s._v(" HAHA/Shark")]),s._v(" "),t("p",[s._v("Absolutely! And it did. But then, we wrote more code. LeakCanary used to depend on "),t("a",{attrs:{href:"https://github.com/square/haha",target:"_blank",rel:"noopener noreferrer"}},[s._v("HAHA"),t("OutboundLink")],1),s._v(", a repackaging of perflib, the heap dump parser used by Android Studio. Unfortunately perflib was slow and used too much memory, so LeakCanary now includes its own heap dump parser: Shark. The extra code comes from "),t("a",{attrs:{href:"https://square.github.io/leakcanary/shark/",target:"_blank",rel:"noopener noreferrer"}},[s._v("Shark"),t("OutboundLink")],1),s._v(", but also from having a lot more automated tests, and an improved UI layer.")]),s._v(" "),t("h2",{attrs:{id:"code"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#code"}},[s._v("#")]),s._v(" code")]),s._v(" "),t("h3",{attrs:{id:"refwatcher"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#refwatcher"}},[s._v("#")]),s._v(" RefWatcher")]),s._v(" "),t("blockquote",[t("p",[t("a",{attrs:{href:"https://github.com/square/leakcanary/blob/v1.5.2/leakcanary-watcher/src/main/java/com/squareup/leakcanary/RefWatcher.java",target:"_blank",rel:"noopener noreferrer"}},[s._v("RefWatcher-1.5.2"),t("OutboundLink")],1)])]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 1.5.2版本的 RefWatcher 实现")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("RefWatcher")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("static")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("RefWatcher")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("DISABLED")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("RefWatcherBuilder")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("build")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("WatchExecutor")]),s._v(" watchExecutor"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DebuggerControl")]),s._v(" debuggerControl"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("GcTrigger")]),s._v(" gcTrigger"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("HeapDumper")]),s._v(" heapDumper"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Set")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" retainedKeys"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ReferenceQueue")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),s._v(" queue"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("HeapDump"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("Listener")]),s._v(" heapdumpListener"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ExcludedRefs")]),s._v(" excludedRefs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("RefWatcher")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("WatchExecutor")]),s._v(" watchExecutor"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("DebuggerControl")]),s._v(" debuggerControl"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("GcTrigger")]),s._v(" gcTrigger"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("HeapDumper")]),s._v(" heapDumper"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("HeapDump"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("Listener")]),s._v(" heapdumpListener"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ExcludedRefs")]),s._v(" excludedRefs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("watchExecutor "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("checkNotNull")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("watchExecutor"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"watchExecutor"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("debuggerControl "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("checkNotNull")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("debuggerControl"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"debuggerControl"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("gcTrigger "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("checkNotNull")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("gcTrigger"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"gcTrigger"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("heapDumper "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("checkNotNull")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("heapDumper"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"heapDumper"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("heapdumpListener "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("checkNotNull")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("heapdumpListener"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"heapdumpListener"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("excludedRefs "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("checkNotNull")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("excludedRefs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"excludedRefs"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n retainedKeys "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("CopyOnWriteArraySet")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n queue "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ReferenceQueue")]),t("span",{pre:!0,attrs:{class:"token generics"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("<")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(">")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/**\n * Identical to {@link #watch(Object, String)} with an empty string reference name.\n *\n * @see #watch(Object, String)\n */")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("watch")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" watchedReference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("watch")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("watchedReference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('""')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("/**\n * Watches the provided references and checks if it can be GCed. This method is non blocking,\n * the check is done on the {@link WatchExecutor} this {@link RefWatcher} has been constructed\n * with.\n *\n * @param referenceName An logical identifier for the watched object.\n */")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("watch")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Object")]),s._v(" watchedReference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" referenceName"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("DISABLED")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("checkNotNull")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("watchedReference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"watchedReference"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("checkNotNull")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("referenceName"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"referenceName"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),s._v(" watchStartNanoTime "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("System")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("nanoTime")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" key "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("UUID")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("randomUUID")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("toString")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n retainedKeys"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("add")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("KeyedWeakReference")]),s._v(" reference "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("KeyedWeakReference")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("watchedReference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" referenceName"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" queue"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("ensureGoneAsync")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("watchStartNanoTime"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("ensureGoneAsync")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),s._v(" watchStartNanoTime"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("KeyedWeakReference")]),s._v(" reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n watchExecutor"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("execute")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Retryable")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Override")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Retryable"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("Result")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("run")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("ensureGone")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" watchStartNanoTime"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@SuppressWarnings")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('"ReferenceEquality"')]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// Explicitly checking for named null.")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Retryable"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("Result")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("ensureGone")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("KeyedWeakReference")]),s._v(" reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),s._v(" watchStartNanoTime"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),s._v(" gcStartNanoTime "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("System")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("nanoTime")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),s._v(" watchDurationMs "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("NANOSECONDS")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("toMillis")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("gcStartNanoTime "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" watchStartNanoTime"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("removeWeaklyReachableReferences")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("debuggerControl"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("isDebuggerAttached")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// The debugger can create false leaks.")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("RETRY")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("gone")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("DONE")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n gcTrigger"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("runGc")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("removeWeaklyReachableReferences")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("gone")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),s._v(" startDumpHeap "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("System")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("nanoTime")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),s._v(" gcDurationMs "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("NANOSECONDS")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("toMillis")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("startDumpHeap "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" gcStartNanoTime"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("File")]),s._v(" heapDumpFile "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" heapDumper"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("dumpHeap")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("heapDumpFile "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("RETRY_LATER")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// Could not dump the heap.")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("RETRY")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),s._v(" heapDumpDurationMs "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("NANOSECONDS")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("toMillis")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("System")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("nanoTime")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("-")]),s._v(" startDumpHeap"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n heapdumpListener"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("analyze")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("new")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("HeapDump")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("heapDumpFile"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("name"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" excludedRefs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" watchDurationMs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n gcDurationMs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" heapDumpDurationMs"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("DONE")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("boolean")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("gone")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("KeyedWeakReference")]),s._v(" reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!")]),s._v("retainedKeys"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("contains")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("reference"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("removeWeaklyReachableReferences")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// WeakReferences are enqueued as soon as the object to which they point to becomes weakly")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// reachable. This is before finalization or garbage collection has actually happened.")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("KeyedWeakReference")]),s._v(" ref"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("while")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ref "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("KeyedWeakReference")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" queue"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("poll")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n retainedKeys"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("remove")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ref"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("key"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br"),t("span",{staticClass:"line-number"},[s._v("39")]),t("br"),t("span",{staticClass:"line-number"},[s._v("40")]),t("br"),t("span",{staticClass:"line-number"},[s._v("41")]),t("br"),t("span",{staticClass:"line-number"},[s._v("42")]),t("br"),t("span",{staticClass:"line-number"},[s._v("43")]),t("br"),t("span",{staticClass:"line-number"},[s._v("44")]),t("br"),t("span",{staticClass:"line-number"},[s._v("45")]),t("br"),t("span",{staticClass:"line-number"},[s._v("46")]),t("br"),t("span",{staticClass:"line-number"},[s._v("47")]),t("br"),t("span",{staticClass:"line-number"},[s._v("48")]),t("br"),t("span",{staticClass:"line-number"},[s._v("49")]),t("br"),t("span",{staticClass:"line-number"},[s._v("50")]),t("br"),t("span",{staticClass:"line-number"},[s._v("51")]),t("br"),t("span",{staticClass:"line-number"},[s._v("52")]),t("br"),t("span",{staticClass:"line-number"},[s._v("53")]),t("br"),t("span",{staticClass:"line-number"},[s._v("54")]),t("br"),t("span",{staticClass:"line-number"},[s._v("55")]),t("br"),t("span",{staticClass:"line-number"},[s._v("56")]),t("br"),t("span",{staticClass:"line-number"},[s._v("57")]),t("br"),t("span",{staticClass:"line-number"},[s._v("58")]),t("br"),t("span",{staticClass:"line-number"},[s._v("59")]),t("br"),t("span",{staticClass:"line-number"},[s._v("60")]),t("br"),t("span",{staticClass:"line-number"},[s._v("61")]),t("br"),t("span",{staticClass:"line-number"},[s._v("62")]),t("br"),t("span",{staticClass:"line-number"},[s._v("63")]),t("br"),t("span",{staticClass:"line-number"},[s._v("64")]),t("br"),t("span",{staticClass:"line-number"},[s._v("65")]),t("br"),t("span",{staticClass:"line-number"},[s._v("66")]),t("br"),t("span",{staticClass:"line-number"},[s._v("67")]),t("br"),t("span",{staticClass:"line-number"},[s._v("68")]),t("br"),t("span",{staticClass:"line-number"},[s._v("69")]),t("br"),t("span",{staticClass:"line-number"},[s._v("70")]),t("br"),t("span",{staticClass:"line-number"},[s._v("71")]),t("br"),t("span",{staticClass:"line-number"},[s._v("72")]),t("br"),t("span",{staticClass:"line-number"},[s._v("73")]),t("br"),t("span",{staticClass:"line-number"},[s._v("74")]),t("br"),t("span",{staticClass:"line-number"},[s._v("75")]),t("br"),t("span",{staticClass:"line-number"},[s._v("76")]),t("br"),t("span",{staticClass:"line-number"},[s._v("77")]),t("br"),t("span",{staticClass:"line-number"},[s._v("78")]),t("br"),t("span",{staticClass:"line-number"},[s._v("79")]),t("br"),t("span",{staticClass:"line-number"},[s._v("80")]),t("br"),t("span",{staticClass:"line-number"},[s._v("81")]),t("br"),t("span",{staticClass:"line-number"},[s._v("82")]),t("br"),t("span",{staticClass:"line-number"},[s._v("83")]),t("br"),t("span",{staticClass:"line-number"},[s._v("84")]),t("br"),t("span",{staticClass:"line-number"},[s._v("85")]),t("br"),t("span",{staticClass:"line-number"},[s._v("86")]),t("br"),t("span",{staticClass:"line-number"},[s._v("87")]),t("br"),t("span",{staticClass:"line-number"},[s._v("88")]),t("br"),t("span",{staticClass:"line-number"},[s._v("89")]),t("br"),t("span",{staticClass:"line-number"},[s._v("90")]),t("br"),t("span",{staticClass:"line-number"},[s._v("91")]),t("br"),t("span",{staticClass:"line-number"},[s._v("92")]),t("br"),t("span",{staticClass:"line-number"},[s._v("93")]),t("br"),t("span",{staticClass:"line-number"},[s._v("94")]),t("br"),t("span",{staticClass:"line-number"},[s._v("95")]),t("br"),t("span",{staticClass:"line-number"},[s._v("96")]),t("br"),t("span",{staticClass:"line-number"},[s._v("97")]),t("br"),t("span",{staticClass:"line-number"},[s._v("98")]),t("br"),t("span",{staticClass:"line-number"},[s._v("99")]),t("br"),t("span",{staticClass:"line-number"},[s._v("100")]),t("br"),t("span",{staticClass:"line-number"},[s._v("101")]),t("br"),t("span",{staticClass:"line-number"},[s._v("102")]),t("br"),t("span",{staticClass:"line-number"},[s._v("103")]),t("br"),t("span",{staticClass:"line-number"},[s._v("104")]),t("br"),t("span",{staticClass:"line-number"},[s._v("105")]),t("br"),t("span",{staticClass:"line-number"},[s._v("106")]),t("br"),t("span",{staticClass:"line-number"},[s._v("107")]),t("br"),t("span",{staticClass:"line-number"},[s._v("108")]),t("br"),t("span",{staticClass:"line-number"},[s._v("109")]),t("br"),t("span",{staticClass:"line-number"},[s._v("110")]),t("br"),t("span",{staticClass:"line-number"},[s._v("111")]),t("br")])]),t("h2",{attrs:{id:"link"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[s._v("#")]),s._v(" link")]),s._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://allenwu.itscoder.com/leakcanary-source",target:"_blank",rel:"noopener noreferrer"}},[s._v("深入理解 Android 之 LeakCanary 源码解析"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/177.eb8d4ef3.js b/assets/js/177.eb8d4ef3.js
new file mode 100644
index 00000000000..d4106bb2c27
--- /dev/null
+++ b/assets/js/177.eb8d4ef3.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[177],{493:function(t,e,r){"use strict";r.r(e);var o=r(4),s=Object(o.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"链接"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#链接"}},[this._v("#")]),this._v(" 链接")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/google/j2objc",target:"_blank",rel:"noopener noreferrer"}},[this._v("j2objc"),t("OutboundLink")],1),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://developers.google.com/j2objc",target:"_blank",rel:"noopener noreferrer"}},[this._v("wiki"),t("OutboundLink")],1)])])])])])}),[],!1,null,null,null);e.default=s.exports}}]);
\ No newline at end of file
diff --git a/assets/js/178.07d342eb.js b/assets/js/178.07d342eb.js
new file mode 100644
index 00000000000..24b4c9990b5
--- /dev/null
+++ b/assets/js/178.07d342eb.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[178],{495:function(s,t,a){"use strict";a.r(t);var n=a(4),e=Object(n.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"handlemessage"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#handlemessage"}},[s._v("#")]),s._v(" handleMessage")]),s._v(" "),t("p",[s._v("HandlerPoster")]),s._v(" "),t("p",[t("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20230806_163943_AIZ6ic.png",alt:"handleMessage"}})]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("public")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("boolean")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("handleMessage")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Message")]),s._v(" msg"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n\t"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("boolean")]),s._v(" rescheduled "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("false")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// todo")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br")])]),t("p",[s._v("上述 queue 的定义如下")]),s._v(" "),t("h2",{attrs:{id:"pendingpostqueue"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#pendingpostqueue"}},[s._v("#")]),s._v(" PendingPostQueue")]),s._v(" "),t("div",{staticClass:"language-java line-numbers-mode"},[t("pre",{pre:!0,attrs:{class:"language-java"}},[t("code",[t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("final")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPostQueue")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Nullable")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" head"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token annotation punctuation"}},[s._v("@Nullable")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("private")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" tail"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPostQueue")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("synchronized")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("void")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("enqueue")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("pendingPost "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("else")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("next "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("else")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("notifyAll")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("synchronized")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("poll")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" pendingPost "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("!=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("next"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("tail "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" pendingPost"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("synchronized")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PendingPost")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("poll")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("int")]),s._v(" maxMillisToWait"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("throws")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("InterruptedException")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("head "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("==")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("wait")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("long")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("maxMillisToWait"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("poll")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),t("div",{staticClass:"line-numbers-wrapper"},[t("span",{staticClass:"line-number"},[s._v("1")]),t("br"),t("span",{staticClass:"line-number"},[s._v("2")]),t("br"),t("span",{staticClass:"line-number"},[s._v("3")]),t("br"),t("span",{staticClass:"line-number"},[s._v("4")]),t("br"),t("span",{staticClass:"line-number"},[s._v("5")]),t("br"),t("span",{staticClass:"line-number"},[s._v("6")]),t("br"),t("span",{staticClass:"line-number"},[s._v("7")]),t("br"),t("span",{staticClass:"line-number"},[s._v("8")]),t("br"),t("span",{staticClass:"line-number"},[s._v("9")]),t("br"),t("span",{staticClass:"line-number"},[s._v("10")]),t("br"),t("span",{staticClass:"line-number"},[s._v("11")]),t("br"),t("span",{staticClass:"line-number"},[s._v("12")]),t("br"),t("span",{staticClass:"line-number"},[s._v("13")]),t("br"),t("span",{staticClass:"line-number"},[s._v("14")]),t("br"),t("span",{staticClass:"line-number"},[s._v("15")]),t("br"),t("span",{staticClass:"line-number"},[s._v("16")]),t("br"),t("span",{staticClass:"line-number"},[s._v("17")]),t("br"),t("span",{staticClass:"line-number"},[s._v("18")]),t("br"),t("span",{staticClass:"line-number"},[s._v("19")]),t("br"),t("span",{staticClass:"line-number"},[s._v("20")]),t("br"),t("span",{staticClass:"line-number"},[s._v("21")]),t("br"),t("span",{staticClass:"line-number"},[s._v("22")]),t("br"),t("span",{staticClass:"line-number"},[s._v("23")]),t("br"),t("span",{staticClass:"line-number"},[s._v("24")]),t("br"),t("span",{staticClass:"line-number"},[s._v("25")]),t("br"),t("span",{staticClass:"line-number"},[s._v("26")]),t("br"),t("span",{staticClass:"line-number"},[s._v("27")]),t("br"),t("span",{staticClass:"line-number"},[s._v("28")]),t("br"),t("span",{staticClass:"line-number"},[s._v("29")]),t("br"),t("span",{staticClass:"line-number"},[s._v("30")]),t("br"),t("span",{staticClass:"line-number"},[s._v("31")]),t("br"),t("span",{staticClass:"line-number"},[s._v("32")]),t("br"),t("span",{staticClass:"line-number"},[s._v("33")]),t("br"),t("span",{staticClass:"line-number"},[s._v("34")]),t("br"),t("span",{staticClass:"line-number"},[s._v("35")]),t("br"),t("span",{staticClass:"line-number"},[s._v("36")]),t("br"),t("span",{staticClass:"line-number"},[s._v("37")]),t("br"),t("span",{staticClass:"line-number"},[s._v("38")]),t("br"),t("span",{staticClass:"line-number"},[s._v("39")]),t("br"),t("span",{staticClass:"line-number"},[s._v("40")]),t("br"),t("span",{staticClass:"line-number"},[s._v("41")]),t("br"),t("span",{staticClass:"line-number"},[s._v("42")]),t("br"),t("span",{staticClass:"line-number"},[s._v("43")]),t("br"),t("span",{staticClass:"line-number"},[s._v("44")]),t("br"),t("span",{staticClass:"line-number"},[s._v("45")]),t("br"),t("span",{staticClass:"line-number"},[s._v("46")]),t("br"),t("span",{staticClass:"line-number"},[s._v("47")]),t("br")])])])}),[],!1,null,null,null);t.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/179.0324299b.js b/assets/js/179.0324299b.js
new file mode 100644
index 00000000000..9cc83b761b8
--- /dev/null
+++ b/assets/js/179.0324299b.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[179],{496:function(t,n,r){"use strict";r.r(n);var s=r(4),e=Object(s.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h2",{attrs:{id:"link"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[this._v("#")]),this._v(" link")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://juejin.cn/post/6921238915143696392",target:"_blank",rel:"noopener noreferrer"}},[this._v("Android事件分发机制三:事件分发工作流程"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);n.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/18.a934f28e.js b/assets/js/18.a934f28e.js
new file mode 100644
index 00000000000..c268bdc2a7c
--- /dev/null
+++ b/assets/js/18.a934f28e.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{337:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/180.776019c3.js b/assets/js/180.776019c3.js
new file mode 100644
index 00000000000..22d05f53b60
--- /dev/null
+++ b/assets/js/180.776019c3.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[180],{497:function(t,a,r){"use strict";r.r(a);var o=r(4),n=Object(o.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("blockquote",[a("p",[t._v("因为业务原因, 我们发现竞品抖音 app 在 harmonyOS 4 上, 通过手势退到后台, 短视频的暂停速度非常快。 而一般的暂停播放方式是在 'Fragment#onPause'. 在手势上滑, 退出到当前应用到后台的场景下, 'Fragment#onPause' 会在动画结束后才会回调。 导致已经退到桌面很久了, 但是音频还没有暂停, 对用户的体验不是很好")])]),t._v(" "),a("p",[a("strong",[t._v("环境")])]),t._v(" "),a("ol",[a("li",[t._v("os: harmonyOS 4")]),t._v(" "),a("li",[t._v("抖音 version: 28.0+")])]),t._v(" "),a("h2",{attrs:{id:"调研"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#调研"}},[t._v("#")]),t._v(" 调研")]),t._v(" "),a("p",[t._v("这里总结了调研的一些思路和步骤")]),t._v(" "),a("ol",[a("li",[a("p",[t._v("harmony 4 开发文档, 了解新特性. "),a("a",{attrs:{href:"https://developer.harmonyos.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("网站"),a("OutboundLink")],1)])]),t._v(" "),a("li",[a("p",[t._v("debug 抖音 app, 见"),a("RouterLink",{attrs:{to:"/pages/2aa5cb/"}},[t._v("链接")]),t._v("。\n在 android 13 系统下,抖音退后台暂停也是通过 "),a("code",[t._v("Fragment#onPause")]),t._v(" 如下图:")],1),t._v(" "),a("p",[a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20240221_163326_NspsUT.png",alt:""}})])]),t._v(" "),a("li",[a("p",[t._v("通过 apktool 反解成 smali: "),a("code",[t._v("apktool d -r {apk}")]),t._v(", 然后搜索, 'harmony' 关键字。这里我先过滤了 'const-string' 指令")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("rg 'const-string' --glob '*.smali' > const_string.txt")])]),t._v(" "),a("li",[a("code",[t._v("rg 'harmony' const_string.txt")]),t._v(": 再次过滤")])])]),t._v(" "),a("li",[a("p",[t._v("frida, objection 查找内存加载模块, 可以看看是否有鸿蒙相关的功能等等")])]),t._v(" "),a("li",[a("p",[t._v("root 鸿蒙 4.0 系统, 对比抖音和拼多多播放器暂停调用堆栈")])])]),t._v(" "),a("h2",{attrs:{id:"结论"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#结论"}},[t._v("#")]),t._v(" 结论")]),t._v(" "),a("p",[t._v("这一篇的结论有些戏剧性: 其实抖音通过手势上滑退到后台, 也采取的 Fragment#onPause 中暂停。但是重点来了: 鸿蒙系统对视频类应用会提前调用 "),a("code",[t._v("onPause")]),t._v(", 让应用页面提前进入 pause, 提前响应视频音频暂停。 (这也是跟华为客服沟通了解到的)")]),t._v(" "),a("RText",{attrs:{text:"申请步骤:"}}),t._v(" "),a("ol",[a("li",[t._v("发送申请邮件过来, 说明下具体背景和情况, 华为内部去评估下看能否给配置\n邮件地址为: "),a("code",[t._v("hwthirdparty@huawei.com、guolulu2@h-partners.com、wangdandan46@h-partners.com、wangpei13@h-partners.com、yanglvhua@h-partners.com")])]),t._v(" "),a("li",[t._v("作废,不能申请")])])],1)}),[],!1,null,null,null);a.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/181.d599efbc.js b/assets/js/181.d599efbc.js
new file mode 100644
index 00000000000..3ed4277ae5f
--- /dev/null
+++ b/assets/js/181.d599efbc.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[181],{498:function(t,a,n){"use strict";n.r(a);var s=n(4),e=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("blockquote",[a("p",[t._v("逆向抖音, 获取 EditText 的实现是 CommentMentionEditText 组件, 借助, 这个名字在 github 上搜索相关的内容")])]),t._v(" "),a("h2",{attrs:{id:"span"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#span"}},[t._v("#")]),t._v(" span")]),t._v(" "),a("p",[t._v("记住一句话: 一切皆 span")]),t._v(" "),a("h3",{attrs:{id:"children"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#children"}},[t._v("#")]),t._v(" children")]),t._v(" "),a("ul",[a("li",[t._v("BackgroundColorSpan: 设置文本背景颜色, 参数传入一个 int 类型的颜色")]),t._v(" "),a("li",[t._v("ForegroundColorSpan: 设置文本颜色, 参数传入一个 int 类型的颜色")]),t._v(" "),a("li",[t._v("ClickableSpan: 设置点击事件, 需要继承这个类重写 onClick 方法")])]),t._v(" "),a("p",[a("a",{attrs:{href:"https://juejin.cn/post/6844904069899747341",target:"_blank",rel:"noopener noreferrer"}},[t._v("更多"),a("OutboundLink")],1)]),t._v(" "),a("p",[t._v("如自定义 emoji, 继承关系可见如下:")]),t._v(" "),a("div",{staticClass:"language-text line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("- CharacterStyle/UpdateLayout\n - MetricAffectingSpan\n - ReplacementSpan\n - DynamicDrawableSpan\n - ImageSpan\n - EmojiSpan\n - SizeEmojiSpan\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br")])]),a("h2",{attrs:{id:"开始"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#开始"}},[t._v("#")]),t._v(" 开始")]),t._v(" "),a("h3",{attrs:{id:"抖音-提示效果"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#抖音-提示效果"}},[t._v("#")]),t._v(" 抖音@提示效果")]),t._v(" "),a("p",[t._v("如下图:\n"),a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20240304_213356_KcJNCq.jpg",alt:""}})]),t._v(" "),a("p",[t._v("通过 frida dump 出来的内存如下:")]),t._v(" "),a("div",{staticClass:"language-json line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-json"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spans"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.DynamicLayout$ChangeWatcher"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.widget.TextView$ChangeWatcher"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.method.TextKeyListener"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.widget.Editor$SpanController"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.Selection$START"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.Selection$END"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.ss.android.ugc.aweme.social.at.utils.MentionHintSpan"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.style.SpellCheckSpan"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"text"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@输入搜索@的人"')]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br"),a("span",{staticClass:"line-number"},[t._v("12")]),a("br"),a("span",{staticClass:"line-number"},[t._v("13")]),a("br"),a("span",{staticClass:"line-number"},[t._v("14")]),a("br"),a("span",{staticClass:"line-number"},[t._v("15")]),a("br"),a("span",{staticClass:"line-number"},[t._v("16")]),a("br"),a("span",{staticClass:"line-number"},[t._v("17")]),a("br"),a("span",{staticClass:"line-number"},[t._v("18")]),a("br"),a("span",{staticClass:"line-number"},[t._v("19")]),a("br"),a("span",{staticClass:"line-number"},[t._v("20")]),a("br"),a("span",{staticClass:"line-number"},[t._v("21")]),a("br"),a("span",{staticClass:"line-number"},[t._v("22")]),a("br"),a("span",{staticClass:"line-number"},[t._v("23")]),a("br"),a("span",{staticClass:"line-number"},[t._v("24")]),a("br"),a("span",{staticClass:"line-number"},[t._v("25")]),a("br"),a("span",{staticClass:"line-number"},[t._v("26")]),a("br"),a("span",{staticClass:"line-number"},[t._v("27")]),a("br"),a("span",{staticClass:"line-number"},[t._v("28")]),a("br"),a("span",{staticClass:"line-number"},[t._v("29")]),a("br"),a("span",{staticClass:"line-number"},[t._v("30")]),a("br"),a("span",{staticClass:"line-number"},[t._v("31")]),a("br"),a("span",{staticClass:"line-number"},[t._v("32")]),a("br"),a("span",{staticClass:"line-number"},[t._v("33")]),a("br"),a("span",{staticClass:"line-number"},[t._v("34")]),a("br"),a("span",{staticClass:"line-number"},[t._v("35")]),a("br"),a("span",{staticClass:"line-number"},[t._v("36")]),a("br"),a("span",{staticClass:"line-number"},[t._v("37")]),a("br")])]),a("p",[t._v("二、在输入"),a("code",[t._v("@1")]),t._v("setText 的调用如下:")]),t._v(" "),a("p",[t._v("其实现也是通过 "),a("code",[t._v("@1 + hint")]),t._v(" 然后 "),a("code",[t._v("remove hint")]),t._v(" 的方式来实现, hint 的提示效果")]),t._v(" "),a("div",{staticClass:"language- line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("EditTextClz: com.ss.android.ugc.aweme.comment.widget.CommentMentionEditText\nViewId: 2131367606\ntext: @1输入搜索@的人\n------------startFlag:48180395,objectHash:253684777,thread(id:2,name:main),timestamp:1709726438706---------------\nandroid.widget.EditText.setText()\n at android.widget.TextView.setText(Native Method)\n at X.pSN.LIZ(SourceFile:17170465)\n at X.pT1.LIZ(SourceFile:50724951)\n at X.pTY.LIZIZ(SourceFile:50724882)\n at X.pTY.LIZ(SourceFile:50659349)\n at X.pT1.LIZ(SourceFile:17104935)\n at X.pT0.LIZ(SourceFile:178)\n at X.pSA.afterTextChanged(SourceFile:17236285)\n at X.pSL.afterTextChanged(SourceFile:17170432)\n at android.widget.TextView.sendAfterTextChanged(TextView.java:11066)\n at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:14164)\n at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1278)\n at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:578)\n at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:508)\n at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:38)\n at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:941)\n at android.view.inputmethod.BaseInputConnection.commitText(BaseInputConnection.java:219)\n at com.android.internal.inputmethod.EditableInputConnection.commitText(EditableInputConnection.java:201)\n at android.view.inputmethod.InputConnectionWrapper.commitText(InputConnectionWrapper.java:200)\n at X.pks.commitText(SourceFile:33685508)\n at com.android.internal.inputmethod.RemoteInputConnectionImpl.lambda$commitText$16$com-android-internal-inputmethod-RemoteInputConnectionImpl(RemoteInputConnectionImpl.java:569)\n at com.android.internal.inputmethod.RemoteInputConnectionImpl$$ExternalSyntheticLambda34.run(Unknown Source:8)\n at android.os.Handler.handleCallback(Handler.java:942)\n at android.os.Handler.dispatchMessage(Handler.java:99)\n at android.os.Looper.loopOnce(Looper.java:201)\n at android.os.Looper.loop(Looper.java:288)\n at android.app.ActivityThread.main(ActivityThread.java:7898)\n at java.lang.reflect.Method.invoke(Native Method)\n at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)\n at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)\n------------endFlag:48180395,usedtime:3---------------\n\nEditTextClz: com.ss.android.ugc.aweme.comment.widget.CommentMentionEditText\nViewId: 2131367606\ntext: @1\n------------startFlag:11062723,objectHash:253684777,thread(id:2,name:main),timestamp:1709726438711---------------\nandroid.widget.EditText.setText()\n at android.widget.TextView.setText(Native Method)\n at X.pSN.LIZ(SourceFile:17170465)\n at X.pT1.LIZ(SourceFile:50724951)\n at X.pTY.LIZIZ(SourceFile:50724882)\n at X.pTY.LIZ(SourceFile:50659349)\n at X.pT1.LIZ(SourceFile:17104935)\n at X.pT0.LIZ(SourceFile:178)\n at X.pSA.afterTextChanged(SourceFile:17236285)\n at X.pSL.afterTextChanged(SourceFile:17170432)\n at android.widget.TextView.sendAfterTextChanged(TextView.java:11066)\n at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:14164)\n at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1278)\n at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:578)\n at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:231)\n at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:38)\n at kotlin.jvm.internal.ALambdaS661S0100000_34.invoke$28(SourceFile:50528282)\n at kotlin.jvm.internal.ALambdaS661S0100000_34.invoke(Unknown Source:18)\n at X.pUO.LIZ(SourceFile:17039414)\n at kotlin.jvm.internal.ALambdaS575S0100000_34.invoke$507(SourceFile:16973835)\n at kotlin.jvm.internal.ALambdaS575S0100000_34.invoke(Unknown Source:167)\n at X.pUO.LIZ(SourceFile:17104928)\n at X.pUO.LIZJ(SourceFile:196626)\n at com.ss.android.ugc.aweme.social.at.utils.MentionHintHelper$handleOnSelectionChanged$1.invoke(SourceFile:33816629)\n at X.pUO.LIZ(SourceFile:17039414)\n at X.pUO.LIZ(SourceFile:33947682)\n at X.pSD.LIZ(SourceFile:33751054)\n at com.ss.android.ugc.aweme.comment.widget.CommentMentionEditText.onSelectionChanged(SourceFile:33685511)\n at android.widget.TextView.spanChange(TextView.java:11224)\n at android.widget.TextView$ChangeWatcher.onSpanChanged(TextView.java:14176)\n at android.text.SpannableStringBuilder.sendSpanChanged(SpannableStringBuilder.java:1308)\n at android.text.SpannableStringBuilder.sendToSpanWatchers(SpannableStringBuilder.java:652)\n at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:581)\n at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:508)\n at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:38)\n at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:941)\n at android.view.inputmethod.BaseInputConnection.commitText(BaseInputConnection.java:219)\n at com.android.internal.inputmethod.EditableInputConnection.commitText(EditableInputConnection.java:201)\n at android.view.inputmethod.InputConnectionWrapper.commitText(InputConnectionWrapper.java:200)\n at X.pks.commitText(SourceFile:33685508)\n at com.android.internal.inputmethod.RemoteInputConnectionImpl.lambda$commitText$16$com-android-internal-inputmethod-RemoteInputConnectionImpl(RemoteInputConnectionImpl.java:569)\n at com.android.internal.inputmethod.RemoteInputConnectionImpl$$ExternalSyntheticLambda34.run(Unknown Source:8)\n at android.os.Handler.handleCallback(Handler.java:942)\n at android.os.Handler.dispatchMessage(Handler.java:99)\n at android.os.Looper.loopOnce(Looper.java:201)\n at android.os.Looper.loop(Looper.java:288)\n at android.app.ActivityThread.main(ActivityThread.java:7898)\n at java.lang.reflect.Method.invoke(Native Method)\n at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)\n at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)\n------------endFlag:11062723,usedtime:3---------------\n\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br"),a("span",{staticClass:"line-number"},[t._v("12")]),a("br"),a("span",{staticClass:"line-number"},[t._v("13")]),a("br"),a("span",{staticClass:"line-number"},[t._v("14")]),a("br"),a("span",{staticClass:"line-number"},[t._v("15")]),a("br"),a("span",{staticClass:"line-number"},[t._v("16")]),a("br"),a("span",{staticClass:"line-number"},[t._v("17")]),a("br"),a("span",{staticClass:"line-number"},[t._v("18")]),a("br"),a("span",{staticClass:"line-number"},[t._v("19")]),a("br"),a("span",{staticClass:"line-number"},[t._v("20")]),a("br"),a("span",{staticClass:"line-number"},[t._v("21")]),a("br"),a("span",{staticClass:"line-number"},[t._v("22")]),a("br"),a("span",{staticClass:"line-number"},[t._v("23")]),a("br"),a("span",{staticClass:"line-number"},[t._v("24")]),a("br"),a("span",{staticClass:"line-number"},[t._v("25")]),a("br"),a("span",{staticClass:"line-number"},[t._v("26")]),a("br"),a("span",{staticClass:"line-number"},[t._v("27")]),a("br"),a("span",{staticClass:"line-number"},[t._v("28")]),a("br"),a("span",{staticClass:"line-number"},[t._v("29")]),a("br"),a("span",{staticClass:"line-number"},[t._v("30")]),a("br"),a("span",{staticClass:"line-number"},[t._v("31")]),a("br"),a("span",{staticClass:"line-number"},[t._v("32")]),a("br"),a("span",{staticClass:"line-number"},[t._v("33")]),a("br"),a("span",{staticClass:"line-number"},[t._v("34")]),a("br"),a("span",{staticClass:"line-number"},[t._v("35")]),a("br"),a("span",{staticClass:"line-number"},[t._v("36")]),a("br"),a("span",{staticClass:"line-number"},[t._v("37")]),a("br"),a("span",{staticClass:"line-number"},[t._v("38")]),a("br"),a("span",{staticClass:"line-number"},[t._v("39")]),a("br"),a("span",{staticClass:"line-number"},[t._v("40")]),a("br"),a("span",{staticClass:"line-number"},[t._v("41")]),a("br"),a("span",{staticClass:"line-number"},[t._v("42")]),a("br"),a("span",{staticClass:"line-number"},[t._v("43")]),a("br"),a("span",{staticClass:"line-number"},[t._v("44")]),a("br"),a("span",{staticClass:"line-number"},[t._v("45")]),a("br"),a("span",{staticClass:"line-number"},[t._v("46")]),a("br"),a("span",{staticClass:"line-number"},[t._v("47")]),a("br"),a("span",{staticClass:"line-number"},[t._v("48")]),a("br"),a("span",{staticClass:"line-number"},[t._v("49")]),a("br"),a("span",{staticClass:"line-number"},[t._v("50")]),a("br"),a("span",{staticClass:"line-number"},[t._v("51")]),a("br"),a("span",{staticClass:"line-number"},[t._v("52")]),a("br"),a("span",{staticClass:"line-number"},[t._v("53")]),a("br"),a("span",{staticClass:"line-number"},[t._v("54")]),a("br"),a("span",{staticClass:"line-number"},[t._v("55")]),a("br"),a("span",{staticClass:"line-number"},[t._v("56")]),a("br"),a("span",{staticClass:"line-number"},[t._v("57")]),a("br"),a("span",{staticClass:"line-number"},[t._v("58")]),a("br"),a("span",{staticClass:"line-number"},[t._v("59")]),a("br"),a("span",{staticClass:"line-number"},[t._v("60")]),a("br"),a("span",{staticClass:"line-number"},[t._v("61")]),a("br"),a("span",{staticClass:"line-number"},[t._v("62")]),a("br"),a("span",{staticClass:"line-number"},[t._v("63")]),a("br"),a("span",{staticClass:"line-number"},[t._v("64")]),a("br"),a("span",{staticClass:"line-number"},[t._v("65")]),a("br"),a("span",{staticClass:"line-number"},[t._v("66")]),a("br"),a("span",{staticClass:"line-number"},[t._v("67")]),a("br"),a("span",{staticClass:"line-number"},[t._v("68")]),a("br"),a("span",{staticClass:"line-number"},[t._v("69")]),a("br"),a("span",{staticClass:"line-number"},[t._v("70")]),a("br"),a("span",{staticClass:"line-number"},[t._v("71")]),a("br"),a("span",{staticClass:"line-number"},[t._v("72")]),a("br"),a("span",{staticClass:"line-number"},[t._v("73")]),a("br"),a("span",{staticClass:"line-number"},[t._v("74")]),a("br"),a("span",{staticClass:"line-number"},[t._v("75")]),a("br"),a("span",{staticClass:"line-number"},[t._v("76")]),a("br"),a("span",{staticClass:"line-number"},[t._v("77")]),a("br"),a("span",{staticClass:"line-number"},[t._v("78")]),a("br"),a("span",{staticClass:"line-number"},[t._v("79")]),a("br"),a("span",{staticClass:"line-number"},[t._v("80")]),a("br"),a("span",{staticClass:"line-number"},[t._v("81")]),a("br"),a("span",{staticClass:"line-number"},[t._v("82")]),a("br"),a("span",{staticClass:"line-number"},[t._v("83")]),a("br"),a("span",{staticClass:"line-number"},[t._v("84")]),a("br"),a("span",{staticClass:"line-number"},[t._v("85")]),a("br"),a("span",{staticClass:"line-number"},[t._v("86")]),a("br"),a("span",{staticClass:"line-number"},[t._v("87")]),a("br"),a("span",{staticClass:"line-number"},[t._v("88")]),a("br"),a("span",{staticClass:"line-number"},[t._v("89")]),a("br"),a("span",{staticClass:"line-number"},[t._v("90")]),a("br"),a("span",{staticClass:"line-number"},[t._v("91")]),a("br"),a("span",{staticClass:"line-number"},[t._v("92")]),a("br"),a("span",{staticClass:"line-number"},[t._v("93")]),a("br")])]),a("h3",{attrs:{id:"抖音-suggestionspan"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#抖音-suggestionspan"}},[t._v("#")]),t._v(" 抖音 SuggestionSpan")]),t._v(" "),a("p",[a("img",{attrs:{src:"https://cdn.jsdelivr.net/gh/jacky1234/picArchieve@master/uPic/20240305_220103_XeZdHb.jpg",alt:""}})]),t._v(" "),a("p",[t._v("注意到 gg 下面有一条红色线条, 原来其为 SuggestionSpan, 内容如下:")]),t._v(" "),a("div",{staticClass:"language-json line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-json"}},[a("code",[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spans"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.DynamicLayout$ChangeWatcher"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.widget.TextView$ChangeWatcher"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.method.TextKeyListener"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.widget.Editor$SpanController"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.Selection$START"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.Selection$END"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.ss.android.ugc.aweme.social.at.MentionEditText$MentionSpan"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanStart"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"spanEnd"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("9")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t\t\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"clazz"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.text.style.SuggestionSpan"')]),t._v("\n\t\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\t"),a("span",{pre:!0,attrs:{class:"token property"}},[t._v('"text"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@福州沁儿 @gg "')]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br"),a("span",{staticClass:"line-number"},[t._v("5")]),a("br"),a("span",{staticClass:"line-number"},[t._v("6")]),a("br"),a("span",{staticClass:"line-number"},[t._v("7")]),a("br"),a("span",{staticClass:"line-number"},[t._v("8")]),a("br"),a("span",{staticClass:"line-number"},[t._v("9")]),a("br"),a("span",{staticClass:"line-number"},[t._v("10")]),a("br"),a("span",{staticClass:"line-number"},[t._v("11")]),a("br"),a("span",{staticClass:"line-number"},[t._v("12")]),a("br"),a("span",{staticClass:"line-number"},[t._v("13")]),a("br"),a("span",{staticClass:"line-number"},[t._v("14")]),a("br"),a("span",{staticClass:"line-number"},[t._v("15")]),a("br"),a("span",{staticClass:"line-number"},[t._v("16")]),a("br"),a("span",{staticClass:"line-number"},[t._v("17")]),a("br"),a("span",{staticClass:"line-number"},[t._v("18")]),a("br"),a("span",{staticClass:"line-number"},[t._v("19")]),a("br"),a("span",{staticClass:"line-number"},[t._v("20")]),a("br"),a("span",{staticClass:"line-number"},[t._v("21")]),a("br"),a("span",{staticClass:"line-number"},[t._v("22")]),a("br"),a("span",{staticClass:"line-number"},[t._v("23")]),a("br"),a("span",{staticClass:"line-number"},[t._v("24")]),a("br"),a("span",{staticClass:"line-number"},[t._v("25")]),a("br"),a("span",{staticClass:"line-number"},[t._v("26")]),a("br"),a("span",{staticClass:"line-number"},[t._v("27")]),a("br"),a("span",{staticClass:"line-number"},[t._v("28")]),a("br"),a("span",{staticClass:"line-number"},[t._v("29")]),a("br"),a("span",{staticClass:"line-number"},[t._v("30")]),a("br"),a("span",{staticClass:"line-number"},[t._v("31")]),a("br"),a("span",{staticClass:"line-number"},[t._v("32")]),a("br"),a("span",{staticClass:"line-number"},[t._v("33")]),a("br"),a("span",{staticClass:"line-number"},[t._v("34")]),a("br"),a("span",{staticClass:"line-number"},[t._v("35")]),a("br"),a("span",{staticClass:"line-number"},[t._v("36")]),a("br"),a("span",{staticClass:"line-number"},[t._v("37")]),a("br")])]),a("h3",{attrs:{id:"处理表情面板-del"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#处理表情面板-del"}},[t._v("#")]),t._v(" 处理表情面板 del")]),t._v(" "),a("p",[t._v("删除有两个地方可以触发: 键盘的 del、表情面板的 del。 这里存在一个问题在键盘 ACTION_DOWN 事件未处理, 会传递给 view 的 ACTION_DOWN, "),a("code",[t._v("InputConnectionWrapper#sendKeyEvent")]),t._v(" 与 "),a("code",[t._v("View#onKey")]),t._v(" 实现一致, 这里需要做事件的去重处理。 代码略")]),t._v(" "),a("h3",{attrs:{id:"占位符的拆分与组装"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#占位符的拆分与组装"}},[t._v("#")]),t._v(" 占位符的拆分与组装")]),t._v(" "),a("p",[t._v("代码牵扯到私密问题, 这里不提供。"),a("RouterLink",{attrs:{to:"/pages/c148a0/"}},[t._v("link")])],1),t._v(" "),a("h2",{attrs:{id:"参考"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#参考"}},[t._v("#")]),t._v(" 参考")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://www.sohu.com/a/281235927_611601",target:"_blank",rel:"noopener noreferrer"}},[t._v("Android 如何优雅地实现@人功能?——仿微博、仿 QQ、仿微信、零入侵、高扩展性 "),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://juejin.cn/post/6844904069899747341",target:"_blank",rel:"noopener noreferrer"}},[t._v("Android 中 Spannable 的使用"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/andydevacc/MentionEditText",target:"_blank",rel:"noopener noreferrer"}},[t._v("MentionEditText"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/search?q=MentionEditTex&type=repositories",target:"_blank",rel:"noopener noreferrer"}},[t._v("github-search-result"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/182.aa7ebbf7.js b/assets/js/182.aa7ebbf7.js
new file mode 100644
index 00000000000..b80ada902c7
--- /dev/null
+++ b/assets/js/182.aa7ebbf7.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[182],{499:function(e,s,n){"use strict";n.r(s);var a=n(4),t=Object(a.a)({},(function(){var e=this,s=e._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[s("blockquote",[s("p",[e._v("探索抖音禁止录屏")])]),e._v(" "),s("h2",{attrs:{id:"flag-secure"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#flag-secure"}},[e._v("#")]),e._v(" FLAG_SECURE")]),e._v(" "),s("p",[e._v("在播放付费短剧内容是,执行 "),s("code",[e._v("adb shell dumpsys window windows | grep -A 30 -E 'Window #|mCurrentFocus'")]),e._v(" 发现当前 window 设置了 flag "),s("code",[e._v("SECURE")]),e._v(". 其定义在 "),s("a",{attrs:{href:"https://developer.android.com/reference/android/view/WindowManager.LayoutParams",target:"_blank",rel:"noopener noreferrer"}},[e._v("/WindowManager.LayoutParams"),s("OutboundLink")],1),e._v(" 中, 此 flag: Added in API level 1.")]),e._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[e._v("/** Window flag: treat the content of the window as secure, preventing\n * it from appearing in screenshots or from being viewed on non-secure\n * displays.\n *\n * See {@link android.view.Display#FLAG_SECURE} for more details about\n * secure surfaces and secure displays.\n */")]),e._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("public")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("static")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("final")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("int")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[e._v("FLAG_SECURE")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[e._v("0x00002000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])]),e._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[e._v("1")]),s("br"),s("span",{staticClass:"line-number"},[e._v("2")]),s("br"),s("span",{staticClass:"line-number"},[e._v("3")]),s("br"),s("span",{staticClass:"line-number"},[e._v("4")]),s("br"),s("span",{staticClass:"line-number"},[e._v("5")]),s("br"),s("span",{staticClass:"line-number"},[e._v("6")]),s("br"),s("span",{staticClass:"line-number"},[e._v("7")]),s("br"),s("span",{staticClass:"line-number"},[e._v("8")]),s("br")])]),s("div",{staticClass:"language-text line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("--\nWindow #13 Window{8c106d1 u0 com.ss.android.ugc.aweme/com.ss.android.ugc.aweme.playlet.videodetail.PlayletVideoPlayActivity}:\n mDisplayId=0 rootTaskId=11350 mSession=Session{7a1d86 21483:u0a10517} mClient=android.os.BinderProxy@cea31f8\n mOwnerUid=10517 showForAllUsers=false package=com.ss.android.ugc.aweme appop=NONE\n mAttrs={(0,0)(fillxfill) sim={adjust=nothing forwardNavigation} ty=BASE_APPLICATION hwFlags=#0 isEmuiStyle=0 statusBarColor=#0 navigationBarColor=#ff000000 wanim=0x10302fe\n fl=KEEP_SCREEN_ON LAYOUT_IN_SCREEN SECURE LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS\n pfl=FIT_INSETS_CONTROLLED\n vsysui=LAYOUT_STABLE LAYOUT_FULLSCREEN\n fitSides=}\n Requested w=720 h=1600 mLayoutSeq=25844\n mBaseLayer=21000 mSubLayer=0 mToken=ActivityRecord{70e4774 u0 com.ss.android.ugc.aweme/.playlet.videodetail.PlayletVideoPlayActivity t11350}\n mActivityRecord=ActivityRecord{70e4774 u0 com.ss.android.ugc.aweme/.playlet.videodetail.PlayletVideoPlayActivity t11350}\n mAppDied=false drawnStateEvaluated=true mightAffectAllDrawn=true\n mViewVisibility=0x0 mHaveFrame=true mObscured=false\n mSeq=0 mSystemUiVisibility=0x500\n mGivenContentInsets=[0,0][0,0] mGivenVisibleInsets=[0,0][0,0]\n mFullConfiguration={1.15 ?mcc?mnc [zh_CN_#Hans] ldltr sw360dp w360dp h776dp 320dpi nrml long port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 720, 1600) mAppBounds=Rect(0, 48 - 720, 1600) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0} suim:1 fontWeightScale:100changeUserFlag:0 s.1 fontWeightAdjustment=0}\n mLastReportedConfiguration={1.15 ?mcc?mnc [zh_CN_#Hans] ldltr sw360dp w360dp h776dp 320dpi nrml long port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 720, 1600) mAppBounds=Rect(0, 48 - 720, 1600) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0} suim:1 fontWeightScale:100changeUserFlag:0 s.1 fontWeightAdjustment=0}\n mHasSurface=true isReadyForDisplay()=true mWindowRemovalAllowed=false\n Frames: containing=[0,0][720,1600] parent=[0,0][720,1600]\n display=[0,0][720,1600]\n content=[0,48][720,1600] visible=[0,48][720,1600]\n decor=[0,0][720,1600]\n mFrame=[0,0][720,1600] last=[0,0][720,1600]\n cutout=DisplayCutout{insets=Rect(0, 48 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(310, 0 - 410, 48), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]}} last=DisplayCutout{insets=Rect(0, 48 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(310, 0 - 410, 48), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]}}\n Cur insets: content=[0,48][0,0] visible=[0,48][0,0] stable=[0,48][0,0] Lst insets: content=[0,48][0,0] visible=[0,48][0,0] stable=[0,48][0,0]\n surface=[0,0][0,0]\n WindowStateAnimator{d0be7e6 com.ss.android.ugc.aweme/com.ss.android.ugc.aweme.playlet.videodetail.PlayletVideoPlayActivity}:\n mSurface=Surface(name=com.ss.android.ugc.aweme/com.ss.android.ugc.aweme.playlet.videodetail.PlayletVideoPlayActivity)/@0x69fceef\n Surface: shown=true layer=0 alpha=1.0 rect=(0.0,0.0) 720 x 1600 transform=(1.0, 0.0, 1.0, 0.0)\n mDrawState=HAS_DRAWN mLastHidden=false\n mEnterAnimationPending=false mSystemDecorRect=[0,0][720,1600] mLastClipRect=[0,0][720,1600]\n--\nWindow #14 Window{13235d u0 com.ss.android.ugc.aweme/com.ss.android.ugc.aweme.detail.ui.DetailActivity}:\n mDisplayId=0 rootTaskId=11350 mSession=Session{7a1d86 21483:u0a10517} mClient=android.os.BinderProxy@9aff934\n mOwnerUid=10517 showForAllUsers=false package=com.ss.android.ugc.aweme appop=NONE\n mAttrs={(0,0)(fillxfill) sim={adjust=nothing forwardNavigation} ty=BASE_APPLICATION hwFlags=#0 isEmuiStyle=0 statusBarColor=#0 navigationBarColor=#ff000000 wanim=0x10302fe\n fl=KEEP_SCREEN_ON LAYOUT_IN_SCREEN SECURE LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS\n pfl=FIT_INSETS_CONTROLLED\n vsysui=LAYOUT_STABLE LAYOUT_FULLSCREEN\n fitSides=}\n Requested w=720 h=1600 mLayoutSeq=25834\n mBaseLayer=21000 mSubLayer=0 mToken=ActivityRecord{4894621 u0 com.ss.android.ugc.aweme/.detail.ui.DetailActivity t11350}\n mActivityRecord=ActivityRecord{4894621 u0 com.ss.android.ugc.aweme/.detail.ui.DetailActivity t11350}\n mAppDied=false drawnStateEvaluated=true mightAffectAllDrawn=true\n mViewVisibility=0x8 mHaveFrame=true mObscured=true\n mSeq=0 mSystemUiVisibility=0x500\n mGivenContentInsets=[0,0][0,0] mGivenVisibleInsets=[0,0][0,0]\n mFullConfiguration={1.15 ?mcc?mnc [zh_CN_#Hans] ldltr sw360dp w360dp h776dp 320dpi nrml long port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 720, 1600) mAppBounds=Rect(0, 48 - 720, 1600) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0} suim:1 fontWeightScale:100changeUserFlag:0 s.1 fontWeightAdjustment=0}\n mLastReportedConfiguration={1.15 ?mcc?mnc [zh_CN_#Hans] ldltr sw360dp w360dp h776dp 320dpi nrml long port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 720, 1600) mAppBounds=Rect(0, 48 - 720, 1600) mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0} suim:1 fontWeightScale:100changeUserFlag:0 s.1 fontWeightAdjustment=0}\n mHasSurface=false isReadyForDisplay()=false mWindowRemovalAllowed=false\n Frames: containing=[0,0][720,1600] parent=[0,0][720,1600]\n display=[0,0][720,1600]\n content=[0,48][720,1600] visible=[0,48][720,1600]\n decor=[0,0][720,1600]\n mFrame=[0,0][720,1600] last=[0,0][720,1600]\n cutout=DisplayCutout{insets=Rect(0, 48 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(310, 0 - 410, 48), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]}} last=DisplayCutout{insets=Rect(0, 48 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(310, 0 - 410, 48), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]}}\n Cur insets: content=[0,48][0,0] visible=[0,48][0,0] stable=[0,48][0,0] Lst insets: content=[0,48][0,0] visible=[0,48][0,0] stable=[0,48][0,0]\n surface=[0,0][0,0]\n WindowStateAnimator{8d3acf7 com.ss.android.ugc.aweme/com.ss.android.ugc.aweme.detail.ui.DetailActivity}:\n mDrawState=NO_SURFACE mLastHidden=true\n mEnterAnimationPending=false mSystemDecorRect=[0,0][720,1600] mLastClipRect=[0,0][720,1600]\n mTmpSize=[0,0][720,1600]\n mForceSeamlesslyRotate=false seamlesslyRotate: pending=null finishedFrameNumber=0\n")])]),e._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[e._v("1")]),s("br"),s("span",{staticClass:"line-number"},[e._v("2")]),s("br"),s("span",{staticClass:"line-number"},[e._v("3")]),s("br"),s("span",{staticClass:"line-number"},[e._v("4")]),s("br"),s("span",{staticClass:"line-number"},[e._v("5")]),s("br"),s("span",{staticClass:"line-number"},[e._v("6")]),s("br"),s("span",{staticClass:"line-number"},[e._v("7")]),s("br"),s("span",{staticClass:"line-number"},[e._v("8")]),s("br"),s("span",{staticClass:"line-number"},[e._v("9")]),s("br"),s("span",{staticClass:"line-number"},[e._v("10")]),s("br"),s("span",{staticClass:"line-number"},[e._v("11")]),s("br"),s("span",{staticClass:"line-number"},[e._v("12")]),s("br"),s("span",{staticClass:"line-number"},[e._v("13")]),s("br"),s("span",{staticClass:"line-number"},[e._v("14")]),s("br"),s("span",{staticClass:"line-number"},[e._v("15")]),s("br"),s("span",{staticClass:"line-number"},[e._v("16")]),s("br"),s("span",{staticClass:"line-number"},[e._v("17")]),s("br"),s("span",{staticClass:"line-number"},[e._v("18")]),s("br"),s("span",{staticClass:"line-number"},[e._v("19")]),s("br"),s("span",{staticClass:"line-number"},[e._v("20")]),s("br"),s("span",{staticClass:"line-number"},[e._v("21")]),s("br"),s("span",{staticClass:"line-number"},[e._v("22")]),s("br"),s("span",{staticClass:"line-number"},[e._v("23")]),s("br"),s("span",{staticClass:"line-number"},[e._v("24")]),s("br"),s("span",{staticClass:"line-number"},[e._v("25")]),s("br"),s("span",{staticClass:"line-number"},[e._v("26")]),s("br"),s("span",{staticClass:"line-number"},[e._v("27")]),s("br"),s("span",{staticClass:"line-number"},[e._v("28")]),s("br"),s("span",{staticClass:"line-number"},[e._v("29")]),s("br"),s("span",{staticClass:"line-number"},[e._v("30")]),s("br"),s("span",{staticClass:"line-number"},[e._v("31")]),s("br"),s("span",{staticClass:"line-number"},[e._v("32")]),s("br"),s("span",{staticClass:"line-number"},[e._v("33")]),s("br"),s("span",{staticClass:"line-number"},[e._v("34")]),s("br"),s("span",{staticClass:"line-number"},[e._v("35")]),s("br"),s("span",{staticClass:"line-number"},[e._v("36")]),s("br"),s("span",{staticClass:"line-number"},[e._v("37")]),s("br"),s("span",{staticClass:"line-number"},[e._v("38")]),s("br"),s("span",{staticClass:"line-number"},[e._v("39")]),s("br"),s("span",{staticClass:"line-number"},[e._v("40")]),s("br"),s("span",{staticClass:"line-number"},[e._v("41")]),s("br"),s("span",{staticClass:"line-number"},[e._v("42")]),s("br"),s("span",{staticClass:"line-number"},[e._v("43")]),s("br"),s("span",{staticClass:"line-number"},[e._v("44")]),s("br"),s("span",{staticClass:"line-number"},[e._v("45")]),s("br"),s("span",{staticClass:"line-number"},[e._v("46")]),s("br"),s("span",{staticClass:"line-number"},[e._v("47")]),s("br"),s("span",{staticClass:"line-number"},[e._v("48")]),s("br"),s("span",{staticClass:"line-number"},[e._v("49")]),s("br"),s("span",{staticClass:"line-number"},[e._v("50")]),s("br"),s("span",{staticClass:"line-number"},[e._v("51")]),s("br"),s("span",{staticClass:"line-number"},[e._v("52")]),s("br"),s("span",{staticClass:"line-number"},[e._v("53")]),s("br"),s("span",{staticClass:"line-number"},[e._v("54")]),s("br"),s("span",{staticClass:"line-number"},[e._v("55")]),s("br"),s("span",{staticClass:"line-number"},[e._v("56")]),s("br"),s("span",{staticClass:"line-number"},[e._v("57")]),s("br"),s("span",{staticClass:"line-number"},[e._v("58")]),s("br"),s("span",{staticClass:"line-number"},[e._v("59")]),s("br"),s("span",{staticClass:"line-number"},[e._v("60")]),s("br"),s("span",{staticClass:"line-number"},[e._v("61")]),s("br"),s("span",{staticClass:"line-number"},[e._v("62")]),s("br"),s("span",{staticClass:"line-number"},[e._v("63")]),s("br"),s("span",{staticClass:"line-number"},[e._v("64")]),s("br")])])])}),[],!1,null,null,null);s.default=t.exports}}]);
\ No newline at end of file
diff --git a/assets/js/183.56cb4517.js b/assets/js/183.56cb4517.js
new file mode 100644
index 00000000000..41feacd4b72
--- /dev/null
+++ b/assets/js/183.56cb4517.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[183],{500:function(s,a,t){"use strict";t.r(a);var n=t(4),e=Object(n.a)({},(function(){var s=this,a=s._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[a("h2",{attrs:{id:"vmpeak-与-vmsize"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#vmpeak-与-vmsize"}},[s._v("#")]),s._v(" VMPeak 与 VMSize")]),s._v(" "),a("p",[s._v("在 Android 系统中,VMPeak 和 VMSize 是进程虚拟内存的相关指标,它们对于应用的内存管理和性能有直接影响。了解这些指标对于优化应用的内存使用、特别是在 32 位设备上的优化非常重要。")]),s._v(" "),a("ol",[a("li",[s._v("VMPeak 和 VMSize 的定义")])]),s._v(" "),a("ul",[a("li",[s._v("VMPeak: 进程所使用的虚拟内存的峰值值。这个值表示自进程启动以来,进程虚拟内存使用的最大值。")]),s._v(" "),a("li",[s._v("VMSize: 当前进程所使用的虚拟内存大小。它表示进程当前的虚拟内存使用量,包括代码、数据、堆和栈等。")])]),s._v(" "),a("ol",{attrs:{start:"2"}},[a("li",[s._v("对进程的影响")])]),s._v(" "),a("ul",[a("li",[s._v("内存使用管理:VMPeak 和 VMSize 是进程内存使用的两个重要指标。过高的 VMSize 可能会导致系统内存不足,尤其在设备 RAM 本身较少时,这可能导致系统频繁进行内存交换(swap)或杀死其他后台进程。")]),s._v(" "),a("li",[s._v("性能影响: 高内存使用会影响应用和系统的整体性能。频繁的垃圾回收(GC)和内存管理开销会增加,导致应用响应变慢。")]),s._v(" "),a("li",[s._v("崩溃风险: 如果 VMPeak 超过系统允许的最大虚拟内存(尤其在 32 位设备上,这个上限通常是 4GB),可能会导致内存分配失败,进而引起应用崩溃。")])]),s._v(" "),a("hr"),s._v(" "),a("RText",{attrs:{text:"虚拟地址空间的理论上限"}}),s._v(" "),a("p",[s._v("在 32 位系统上,虚拟地址空间的理论上限是 4 GB(2^32 字节)。但是,由于操作系统和硬件保留了部分地址空间,实际应用程序可用的虚拟地址空间会少于 4 GB。")]),s._v(" "),a("p",[s._v("详细分析")]),s._v(" "),a("ol",[a("li",[s._v("理论最大值:\n32 位地址空间可以表示 4,294,967,296 字节(4 GB)。")]),s._v(" "),a("li",[s._v("实际可用空间:\n内核空间: 在许多 32 位操作系统中,内核和操作系统会占用一部分地址空间。例如,Linux 通常将最高的 1 GB 地址空间保留给内核,这意味着用户态程序可以使用的地址空间大约是 3 GB。\n系统保留和硬件映射: 系统和硬件还会保留部分地址空间用于硬件设备的内存映射和其他用途。")])]),s._v(" "),a("h2",{attrs:{id:"查看-vmsize"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#查看-vmsize"}},[s._v("#")]),s._v(" 查看 VmSize")]),s._v(" "),a("div",{staticClass:"language-shell line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-shell"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 获取 pid")]),s._v("\nadb shell "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("ps")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v("process_name"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("# 查看 VmSize")]),s._v("\nadb shell "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("cat")]),s._v(" /proc/"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("<")]),s._v("pid"),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">")]),s._v("/status "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("|")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("grep")]),s._v(" VmSize\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br")])]),a("h2",{attrs:{id:"_32-位设备上的优化建议"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_32-位设备上的优化建议"}},[s._v("#")]),s._v(" 32 位设备上的优化建议")]),s._v(" "),a("p",[s._v("针对 32 位设备,内存限制更为严格,因为它们的虚拟地址空间有限(最大 4GB,但通常系统和其他应用占用一部分,因此实际可用远小于 4GB)。可以采取以下优化措施:")]),s._v(" "),a("p",[s._v("1.内存优化策略:")]),s._v(" "),a("ul",[a("li",[a("p",[s._v("减少内存使用: 优化代码,减少不必要的对象创建和资源加载,特别是大对象和图像资源。")])]),s._v(" "),a("li",[a("p",[s._v("使用高效数据结构: 选择合适的数据结构,避免使用过多的链表、哈希表等占用大量内存的数据结构。")]),s._v(" "),a("p",[s._v("2.资源管理:")])]),s._v(" "),a("li",[a("p",[s._v("按需加载: 使用按需加载技术,只在需要时加载资源。避免在启动时加载所有资源。")])]),s._v(" "),a("li",[a("p",[s._v("释放不需要的资源: 及时释放不再需要的资源,特别是大图片、音频和视频文件。")])]),s._v(" "),a("li",[a("p",[s._v("优化图像: 使用压缩图像格式(如 WebP),并根据设备屏幕分辨率加载适当尺寸的图像。")]),s._v(" "),a("p",[s._v("3.内存分析工具:")])]),s._v(" "),a("li",[a("p",[s._v("使用 Android Profiler: 通过 Android Studio 提供的内存分析工具,监控应用的内存使用,查找和修复内存泄漏。")])]),s._v(" "),a("li",[a("p",[s._v("LeakCanary: 集成内存泄漏检测工具,如 LeakCanary,自动检测和报告内存泄漏。")]),s._v(" "),a("p",[s._v("4.优化代码:")])]),s._v(" "),a("li",[a("p",[s._v("减少全局变量和单例: 避免过多使用全局变量和单例,它们会在整个应用生命周期中占用内存。")])]),s._v(" "),a("li",[a("p",[s._v("优化算法: 确保算法的时间和空间复杂度最低,避免使用高复杂度的算法。")]),s._v(" "),a("p",[s._v("5.垃圾回收优化:")])]),s._v(" "),a("li",[a("p",[s._v("减少临时对象创建: 尽量减少临时对象的创建,减少垃圾回收的频率。")])]),s._v(" "),a("li",[a("p",[s._v("使用池化技术: 对于频繁使用的大对象,使用对象池(object pool)来重用对象,避免频繁的创建和销毁。")])])]),s._v(" "),a("p",[s._v("通过以上措施,可以有效降低 VMPeak 和 VMSize,从而减少崩溃风险,提升应用在 32 位设备上的性能和稳定性。")]),s._v(" "),a("h2",{attrs:{id:"base"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#base"}},[s._v("#")]),s._v(" base")]),s._v(" "),a("h3",{attrs:{id:"获取-cpu-abis"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#获取-cpu-abis"}},[s._v("#")]),s._v(" 获取 CPU ABIS")]),s._v(" "),a("div",{staticClass:"language-java line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 获取支持的cpu abi,返回一个数组。如 ['arm64-v8a', 'armeabi-v7a', 'armeabi']")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[s._v("SUPPORTED_ABIS")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 设备的主要 CPU 架构,armeabi-v7a. 可以拿到运行时主CPU架构。 另外也可以通过 ApplicationInfo 对象拿")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[s._v("CPU_ABI")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 设备的次要 CPU 架构")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[s._v("CPU_ABI2")]),s._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// 通过 ApplicationInfo 对象拿")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PackageManager")]),s._v(" pm "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getPackageManager")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),s._v(" packageName "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getPackageName")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("try")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ApplicationInfo")]),s._v(" ai "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" pm"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getApplicationInfo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("packageName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("PackageManager")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[s._v("GET_META_DATA")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v(" supportedABIs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("if")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[s._v("VERSION")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[s._v("SDK_INT")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v(">=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Build")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[s._v("VERSION_CODES")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token constant"}},[s._v("LOLLIPOP")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Field")]),s._v(" primaryCpuAbi "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ApplicationInfo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"primaryCpuAbi"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n primaryCpuAbi"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAccessible")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AsyncPLog")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("i")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"xxx"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"primaryCpuAbi=%s"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" primaryCpuAbi"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("get")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ai"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Field")]),s._v(" secondaryCpuAbi "),a("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("ApplicationInfo")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("class")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("getField")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"secondaryCpuAbi"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n secondaryCpuAbi"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("setAccessible")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token boolean"}},[s._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("AsyncPLog")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("i")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"xxx"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[s._v('"secondaryCpuAbi=%s"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" secondaryCpuAbi"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("get")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("ai"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("catch")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[s._v("Exception")]),s._v(" e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n e"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[s._v("printStackTrace")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])]),s._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[s._v("1")]),a("br"),a("span",{staticClass:"line-number"},[s._v("2")]),a("br"),a("span",{staticClass:"line-number"},[s._v("3")]),a("br"),a("span",{staticClass:"line-number"},[s._v("4")]),a("br"),a("span",{staticClass:"line-number"},[s._v("5")]),a("br"),a("span",{staticClass:"line-number"},[s._v("6")]),a("br"),a("span",{staticClass:"line-number"},[s._v("7")]),a("br"),a("span",{staticClass:"line-number"},[s._v("8")]),a("br"),a("span",{staticClass:"line-number"},[s._v("9")]),a("br"),a("span",{staticClass:"line-number"},[s._v("10")]),a("br"),a("span",{staticClass:"line-number"},[s._v("11")]),a("br"),a("span",{staticClass:"line-number"},[s._v("12")]),a("br"),a("span",{staticClass:"line-number"},[s._v("13")]),a("br"),a("span",{staticClass:"line-number"},[s._v("14")]),a("br"),a("span",{staticClass:"line-number"},[s._v("15")]),a("br"),a("span",{staticClass:"line-number"},[s._v("16")]),a("br"),a("span",{staticClass:"line-number"},[s._v("17")]),a("br"),a("span",{staticClass:"line-number"},[s._v("18")]),a("br"),a("span",{staticClass:"line-number"},[s._v("19")]),a("br"),a("span",{staticClass:"line-number"},[s._v("20")]),a("br"),a("span",{staticClass:"line-number"},[s._v("21")]),a("br"),a("span",{staticClass:"line-number"},[s._v("22")]),a("br"),a("span",{staticClass:"line-number"},[s._v("23")]),a("br"),a("span",{staticClass:"line-number"},[s._v("24")]),a("br"),a("span",{staticClass:"line-number"},[s._v("25")]),a("br"),a("span",{staticClass:"line-number"},[s._v("26")]),a("br")])]),a("ul",[a("li",[a("code",[s._v('aapt dump badging your_apk_file.apk | grep "native-code"')]),s._v(": 查看 apk 是 32 位还是 64 位")]),s._v(" "),a("li",[a("code",[s._v('adb shell dumpsys package | grep "cpuAbi"')]),s._v(": 通过 adb 查看架构, not worked")]),s._v(" "),a("li",[a("code",[s._v("adb shell getprop ro.product.cpu.abilist")]),s._v(": 查看系统支持的 cpu 架构")])])],1)}),[],!1,null,null,null);a.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/184.0d015402.js b/assets/js/184.0d015402.js
new file mode 100644
index 00000000000..2ebcc986ae2
--- /dev/null
+++ b/assets/js/184.0d015402.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[184],{501:function(t,e,a){"use strict";a.r(e);var r=a(4),n=Object(r.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"属性"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#属性"}},[t._v("#")]),t._v(" 属性")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("android:angle")]),t._v(": 整型 渐变角度(PS: 当angle=0时,渐变色是从左向右。 然后逆时针方向转,当angle=90时为从下往上。angle必须为45的整数倍)")])]),t._v(" "),e("h2",{attrs:{id:"link"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[t._v("#")]),t._v(" link")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://cloud.tencent.com/developer/article/1013183",target:"_blank",rel:"noopener noreferrer"}},[t._v("Android GradientDrawable(shape标签定义) 静态使用和动态使用(圆角,渐变实现)"),e("OutboundLink")],1)])])])}),[],!1,null,null,null);e.default=n.exports}}]);
\ No newline at end of file
diff --git a/assets/js/185.b95fa9cc.js b/assets/js/185.b95fa9cc.js
new file mode 100644
index 00000000000..174575193ce
--- /dev/null
+++ b/assets/js/185.b95fa9cc.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[185],{502:function(t,s,a){"use strict";a.r(s);var n=a(4),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"window的softinputmode"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#window的softinputmode"}},[t._v("#")]),t._v(" window的SoftInputMode")]),t._v(" "),s("ul",[s("li",[t._v("SOFT_INPUT_ADJUST_PAN")]),t._v(" "),s("li",[t._v("SOFT_INPUT_ADJUST_RESIZE")]),t._v(" "),s("li",[t._v("SOFT_INPUT_STATE_ALWAYS_VISIBLE")]),t._v(" "),s("li",[t._v("SOFT_INPUT_STATE_ALWAYS_HIDDEN")])]),t._v(" "),s("h2",{attrs:{id:"case"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#case"}},[t._v("#")]),t._v(" case")]),t._v(" "),s("h3",{attrs:{id:"软键盘中window的flag设置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#软键盘中window的flag设置"}},[t._v("#")]),t._v(" 软键盘中window的Flag设置")]),t._v(" "),s("blockquote",[s("p",[s("a",{attrs:{href:"https://developer.android.com/reference/android/view/WindowManager.LayoutParams",target:"_blank",rel:"noopener noreferrer"}},[t._v("WindowManager.LayoutParams"),s("OutboundLink")],1)])]),t._v(" "),s("div",{staticClass:"language-java line-numbers-mode"},[s("pre",{pre:!0,attrs:{class:"language-java"}},[s("code",[s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Window")]),t._v(" window "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dialog"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getWindow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("window "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setFlags")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WindowManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LayoutParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FLAG_NOT_TOUCH_MODAL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WindowManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LayoutParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FLAG_NOT_TOUCH_MODAL")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setLayout")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ViewGroup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LayoutParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("MATCH_PARENT")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("ViewGroup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LayoutParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("MATCH_PARENT")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setGravity")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Gravity")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("TOP")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("VERSION")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SDK_INT")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Build")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("VERSION_CODES")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("LOLLIPOP")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addFlags")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WindowManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LayoutParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setStatusBarColor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getResources")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getColor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token generics"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSoftInputMode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WindowManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LayoutParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SOFT_INPUT_ADJUST_PAN")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("showEmoji"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("isBottomContainerEmpty"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSoftInputMode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WindowManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LayoutParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SOFT_INPUT_ADJUST_RESIZE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSoftInputMode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WindowManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LayoutParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SOFT_INPUT_STATE_ALWAYS_VISIBLE")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSoftInputMode")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("WindowManager"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("LayoutParams")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("SOFT_INPUT_STATE_ALWAYS_HIDDEN")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])]),t._v(" "),s("div",{staticClass:"line-numbers-wrapper"},[s("span",{staticClass:"line-number"},[t._v("1")]),s("br"),s("span",{staticClass:"line-number"},[t._v("2")]),s("br"),s("span",{staticClass:"line-number"},[t._v("3")]),s("br"),s("span",{staticClass:"line-number"},[t._v("4")]),s("br"),s("span",{staticClass:"line-number"},[t._v("5")]),s("br"),s("span",{staticClass:"line-number"},[t._v("6")]),s("br"),s("span",{staticClass:"line-number"},[t._v("7")]),s("br"),s("span",{staticClass:"line-number"},[t._v("8")]),s("br"),s("span",{staticClass:"line-number"},[t._v("9")]),s("br"),s("span",{staticClass:"line-number"},[t._v("10")]),s("br"),s("span",{staticClass:"line-number"},[t._v("11")]),s("br"),s("span",{staticClass:"line-number"},[t._v("12")]),s("br"),s("span",{staticClass:"line-number"},[t._v("13")]),s("br"),s("span",{staticClass:"line-number"},[t._v("14")]),s("br"),s("span",{staticClass:"line-number"},[t._v("15")]),s("br"),s("span",{staticClass:"line-number"},[t._v("16")]),s("br"),s("span",{staticClass:"line-number"},[t._v("17")]),s("br"),s("span",{staticClass:"line-number"},[t._v("18")]),s("br"),s("span",{staticClass:"line-number"},[t._v("19")]),s("br"),s("span",{staticClass:"line-number"},[t._v("20")]),s("br")])])])}),[],!1,null,null,null);s.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/186.79fa5799.js b/assets/js/186.79fa5799.js
new file mode 100644
index 00000000000..636d3da9dc3
--- /dev/null
+++ b/assets/js/186.79fa5799.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[186],{503:function(t,a,r){"use strict";r.r(a);var e=r(4),l=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("blockquote",[a("p",[a("a",{attrs:{href:"https://juejin.cn/post/6981731047855620104",target:"_blank",rel:"noopener noreferrer"}},[t._v("颜色值透明度的百分数对应十六进制表"),a("OutboundLink")],1)])]),t._v(" "),a("p",[t._v("ARGB 依次代表透明度(alpha)、红色(red)、绿色(green)、蓝色(blue)。以颜色值 "),a("code",[t._v("#FF66CC99")]),t._v(" 为例, 其中, FF 是透明度, 66 是红色值, CC 是绿色值, 99 是蓝色值。")]),t._v(" "),a("h2",{attrs:{id:"alpha"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#alpha"}},[t._v("#")]),t._v(" alpha")]),t._v(" "),a("ul",[a("li",[t._v("透明度分为 256 个等级, 即 0 - 256, 0 就是透明, 255 就是不透明, 透明度 0(透明) –> 255(不透明) 对应着 16 进制 00(透明) –> FF(不透明), 比如: 50% 透明度;50% 也就是 256 的一半即 128, 因为是从 0 开始算的, 所以是 127, 转换成 16 进制就是 7F")]),t._v(" "),a("li",[t._v("透明度和 不透明度 是两个概念, 它们加起来是 1, 或者 100%.")]),t._v(" "),a("li",[t._v("ARGB 中的透明度 alpha, 表示的是不透明度。")])]),t._v(" "),a("h2",{attrs:{id:"link"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#link"}},[t._v("#")]),t._v(" link")]),t._v(" "),a("ul",[a("li",[a("a",{attrs:{href:"https://www.fly63.com/tool/color/",target:"_blank",rel:"noopener noreferrer"}},[t._v("rgb(a)、hex、hsl(a)、hsv(a)颜色转换工具"),a("OutboundLink")],1)])])])}),[],!1,null,null,null);a.default=l.exports}}]);
\ No newline at end of file
diff --git a/assets/js/187.55660f9b.js b/assets/js/187.55660f9b.js
new file mode 100644
index 00000000000..a86ca56b53d
--- /dev/null
+++ b/assets/js/187.55660f9b.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[187],{505:function(_,v,t){"use strict";t.r(v);var e=t(4),l=Object(e.a)({},(function(){var _=this,v=_._self._c;return v("ContentSlotsDistributor",{attrs:{"slot-key":_.$parent.slotKey}},[v("blockquote",[v("p",[_._v("本方法使用灰度值来辨别白屏")])]),_._v(" "),v("p",[_._v("白色的RGB值为(255, 255, 255), 在灰度转换的情况下, 根据给定的转换公式 "),v("code",[_._v("Gray = (Rx4 + Gx10 + Bx2) >> 8")]),_._v(", 计算得到的灰度值为: "),v("code",[_._v("Gray=(255x4+255x10+255x2)>>8=(1020+2550+510)>>8=4080>>8=15")])]),_._v(" "),v("h2",{attrs:{id:"方案"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#方案"}},[_._v("#")]),_._v(" 方案")]),_._v(" "),v("ul",[v("li",[_._v("根据(x,y,w,h)取出指定区域的图像")]),_._v(" "),v("li",[_._v("将图片每个像素点的(R,G,B)转换为灰度值(0-15), 转换公式如下:\n"),v("code",[_._v("Gray = (Rx4 + Gx10 + Bx2) >> 8")])]),_._v(" "),v("li",[_._v("统计Gray的分布情况, 把各个灰度值的情况上报")]),_._v(" "),v("li",[_._v("为了避免过多上报, 我们会先计算一下白色的占比, 计算公式如下:\n"),v("code",[_._v("whiteRate = GrayArr[15] / TotalPixels")])]),_._v(" "),v("li",[_._v("当whiteRate大于0.9 (配置中心可配web.white_rate_threshold)我们才会上报")]),_._v(" "),v("li",[_._v("我们只能截屏幕可见区域的指定部分, 如果用户有滚动, 那么截取的可能就不是首屏的内容了")])]),_._v(" "),v("h2",{attrs:{id:"检测原理"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#检测原理"}},[_._v("#")]),_._v(" 检测原理")]),_._v(" "),v("p",[_._v("这个白屏检测的原理基于对截取图像的灰度分布进行分析。具体步骤如下:")]),_._v(" "),v("ul",[v("li",[_._v("截取指定区域的图像: 根据给定的区域参数(x,y,w,h), 从屏幕截取指定位置的图像。")]),_._v(" "),v("li",[_._v("将图片每个像素点的(R,G,B)转换为灰度值: 对截取的图像进行灰度转换。"),v("RText",{attrs:{text:"灰度值是图像亮度的表示, 用一个数值表示整个像素的明暗程度"}}),_._v("。根据给定的转换公式 "),v("code",[_._v("Gray = (Rx4 + Gx10 + Bx2) >> 8")]),_._v(", 计算每个像素点的灰度值, 范围为0到15。")],1),_._v(" "),v("li",[_._v("统计灰度值的分布情况: 统计转换后的灰度值的分布情况, 得到每个灰度值出现的次数或比例。")]),_._v(" "),v("li",[_._v("计算白色占比: 根据灰度值的分布情况, 计算白色(灰度值为15)的占比, 即白色像素点在总像素点中的比例。")]),_._v(" "),v("li",[_._v("白屏检测: 当白色占比大于设定的阈值(例如0.9), 即白色像素点占据了大部分图像区域, 认为截取到的内容可能是白屏。")])]),_._v(" "),v("p",[_._v("这种方法的原理是基于白屏通常是整个屏幕大部分区域都是白色的特点。通过分析截取图像的灰度分布情况, 尤其是白色(灰度值最高)的占比, 可以判断当前页面是否呈现出白屏状态。这种方法可以有效避免截取到无效的白屏内容, 并且节省了上报的资源开销。")]),_._v(" "),v("h3",{attrs:{id:"灰度图像公式"}},[v("a",{staticClass:"header-anchor",attrs:{href:"#灰度图像公式"}},[_._v("#")]),_._v(" 灰度图像公式")]),_._v(" "),v("p",[v("code",[_._v("Gray = (Rx4 + Gx10 + Bx2) >> 8")]),_._v(" 是一个用于将彩色图像转换为灰度图像的公式。这个公式通过计算 RGB 三个通道的加权和来得到灰度值,其中绿色通道的权重较大,表明绿色对灰度值的影响最大。")]),_._v(" "),v("p",[_._v("让我们详细分析一下:")]),_._v(" "),v("RText",{attrs:{text:"公式含义:"}}),_._v(" "),v("ul",[v("li",[_._v("R:表示红色通道的值。")]),_._v(" "),v("li",[_._v("G:表示绿色通道的值。")]),_._v(" "),v("li",[_._v("B:表示蓝色通道的值。")]),_._v(" "),v("li",[_._v("Gray:表示最终的灰度值。")]),_._v(" "),v("li",[v("code",[_._v(">> 8")]),_._v(":表示右移 8 位,相当于除以 256。")])]),_._v(" "),v("RText",{attrs:{text:"加权平均:"}}),_._v(" "),v("p",[_._v("这个公式将红色、绿色、蓝色三个通道的值按照不同的权重加在一起:")]),_._v(" "),v("ul",[v("li",[_._v("红色的权重是 4。")]),_._v(" "),v("li",[_._v("绿色的权重是 10,比其他两个通道更高,反映了人眼对绿色更为敏感。")]),_._v(" "),v("li",[_._v("蓝色的权重是 2,相对较低。")])]),_._v(" "),v("p",[_._v("将它们加权后除以 256 来得到一个 0 到 15 的灰度值。")]),_._v(" "),v("RText",{attrs:{text:"具体步骤:"}}),_._v(" "),v("ul",[v("li",[_._v("计算加权值:"),v("code",[_._v("Rx4 + Gx10 + Bx2")]),_._v("。")]),_._v(" "),v("li",[_._v("红色的贡献是 "),v("code",[_._v("Rx4")])]),_._v(" "),v("li",[_._v("绿色的贡献是 "),v("code",[_._v("Gx10")])]),_._v(" "),v("li",[_._v("蓝色的贡献是 "),v("code",[_._v("Bx2")])]),_._v(" "),v("li",[_._v("右移 8 位:"),v("code",[_._v(">> 8")]),_._v(",即将计算结果除以 256。右移操作可以快速实现这种整数除法。")])]),_._v(" "),v("RText",{attrs:{text:"理由:"}}),_._v(" "),v("p",[_._v("使用加权平均是因为人眼对不同颜色的敏感度不同,通常对绿色最敏感,对红色次之,对蓝色最不敏感。这个公式中赋予了绿色较大的权重(10),而红色和蓝色的权重较小(4 和 2)。")]),_._v(" "),v("RText",{attrs:{text:"总结:"}}),_._v(" "),v("ul",[v("li",[_._v("红色、绿色 和 蓝色通道按照不同的权重加在一起,计算得到灰度值。")]),_._v(" "),v("li",[_._v("绿色的权重较高,符合人眼的感知特性。")]),_._v(" "),v("li",[_._v("通过位移操作快速实现除法来缩放结果到 0-255 范围内。")])])],1)}),[],!1,null,null,null);v.default=l.exports}}]);
\ No newline at end of file
diff --git a/assets/js/188.58d3435d.js b/assets/js/188.58d3435d.js
new file mode 100644
index 00000000000..3ed8879ef3c
--- /dev/null
+++ b/assets/js/188.58d3435d.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[188],{504:function(t,a,s){"use strict";s.r(a);var n=s(4),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"getidentifier"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getidentifier"}},[t._v("#")]),t._v(" getIdentifier")]),t._v(" "),a("div",{staticClass:"language-java line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[t._v("val layoutID"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("resources"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getIdentifier")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"activity_main"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"layout"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("packageName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setContentView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("layoutID"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setContentView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("R")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("layout"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("activity_main"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br"),a("span",{staticClass:"line-number"},[t._v("3")]),a("br"),a("span",{staticClass:"line-number"},[t._v("4")]),a("br")])]),a("blockquote",[a("p",[t._v("这两种形式在功能上都是设置一个活动(Activity)的布局(layout),但它们在实现和使用场景上有一些区别。")])]),t._v(" "),a("p",[t._v("A. "),a("code",[t._v("setContentView(R.layout.activity_main)")]),t._v(": 这是最常见和直接的方式来设置活动的布局。在编译时,Android 会根据 "),a("code",[t._v("res/layout/activity_main.xml")]),t._v(" 文件生成一个对应的 "),a("code",[t._v("R.layout.activity_main")]),t._v(" 常量。这个常量是一个静态整数 ID,指向布局资源。使用这种方式,代码简洁明了,容易理解和维护。")]),t._v(" "),a("p",[t._v("B. "),a("code",[t._v("setContentView(layoutID)")]),t._v(": 这种方式首先通过 resources.getIdentifier 方法在运行时动态获取资源 ID,然后再将其设置为内容视图。具体实现如下:")]),t._v(" "),a("div",{staticClass:"language-java line-numbers-mode"},[a("pre",{pre:!0,attrs:{class:"language-java"}},[a("code",[t._v("val layoutID "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" resources"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("getIdentifier")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"activity_main"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"layout"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" packageName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("setContentView")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("layoutID"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])]),t._v(" "),a("div",{staticClass:"line-numbers-wrapper"},[a("span",{staticClass:"line-number"},[t._v("1")]),a("br"),a("span",{staticClass:"line-number"},[t._v("2")]),a("br")])]),a("RText",{attrs:{text:"使用场景"}}),t._v(" "),a("ol",[a("li",[t._v("动态资源加载:")])]),t._v(" "),a("ul",[a("li",[t._v("多布局支持: 如果你的应用需要在运行时根据某些条件(例如设备类型、用户设置、语言环境等)动态选择布局文件,可以使用这种方法。例如,可以根据屏幕尺寸加载不同的布局文件。")]),t._v(" "),a("li",[t._v("模块化资源: 在一些复杂项目中,布局文件可能会被动态地添加或移除。在这种情况下,使用字符串资源名称可以提供更灵活的资源管理方式。")])]),t._v(" "),a("ol",{attrs:{start:"2"}},[a("li",[t._v("国际化和本地化:")])]),t._v(" "),a("ul",[a("li",[t._v("多语言支持: 通过 getIdentifier,可以更方便地在代码中处理不同语言环境下的资源。例如,不同语言环境可能有不同的布局文件命名。")])]),t._v(" "),a("ol",{attrs:{start:"3"}},[a("li",[t._v("插件化和动态更新:")])]),t._v(" "),a("ul",[a("li",[t._v("插件系统: 如果你的应用有插件系统,并且插件的布局文件是动态加载的,那么可以使用这种方法来动态解析和加载插件资源。")]),t._v(" "),a("li",[t._v("热更新: 对于需要从服务器动态获取并加载布局文件的应用,可以在下载新的布局文件后,通过资源名称动态获取其 ID 并设置内容视图。")])]),t._v(" "),a("RText",{attrs:{text:"注意事项:"}}),t._v(" "),a("ul",[a("li",[t._v("性能:resources.getIdentifier 是一个相对耗时的操作,因为它是在运行时解析资源 ID。对于频繁调用的场景,要注意性能开销。")]),t._v(" "),a("li",[t._v("安全性: 动态获取资源 ID 的方式可能会因为资源名称拼写错误或者资源不存在而导致 layoutID 返回 0,从而引发 NullPointerException 或其他错误。因此,需要添加适当的错误处理。")]),t._v(" "),a("li",[t._v("代码可读性: 这种方式的代码可读性较低,维护起来可能不如直接使用 R.layout.activity_main 方便。")])])],1)}),[],!1,null,null,null);a.default=e.exports}}]);
\ No newline at end of file
diff --git a/assets/js/189.229c2265.js b/assets/js/189.229c2265.js
new file mode 100644
index 00000000000..3f0bf70ee02
--- /dev/null
+++ b/assets/js/189.229c2265.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[189],{507:function(e,s,t){"use strict";t.r(s);var a=t(4),i=Object(a.a)({},(function(){var e=this,s=e._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[s("p",[e._v("Deep Link(深度链接)是一种URL或链接,能够将用户直接引导到移动应用或网页中的特定内容或页面,而不仅仅是打开主页。这种链接提供了一种更直接和便捷的用户体验,特别是在移动应用程序中。")]),e._v(" "),s("h2",{attrs:{id:"分类"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#分类"}},[e._v("#")]),e._v(" 分类")]),e._v(" "),s("p",[e._v("根据具体的实现方式和使用场景,Deep Link 有几种类型:")]),e._v(" "),s("h3",{attrs:{id:"传统深度链接-classic-deep-links"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#传统深度链接-classic-deep-links"}},[e._v("#")]),e._v(" 传统深度链接(Classic Deep Links)")]),e._v(" "),s("ul",[s("li",[e._v("功能: 将用户从一个应用程序、网页或其他媒介引导到另一个应用中的特定页面或内容。")]),e._v(" "),s("li",[e._v("局限: 只能在应用已经安装的情况下工作。如果用户未安装该应用,点击深度链接将导致错误或无法打开。")])]),e._v(" "),s("p",[e._v("示例: "),s("code",[e._v("myapp://profile/123")]),e._v(" 可以直接打开应用中的某个用户的个人资料页面,而不是应用的主页。")]),e._v(" "),s("h3",{attrs:{id:"延迟深度链接-deferred-deep-links"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#延迟深度链接-deferred-deep-links"}},[e._v("#")]),e._v(" 延迟深度链接(Deferred Deep Links)")]),e._v(" "),s("ul",[s("li",[e._v("功能: 不仅在应用已安装时引导用户到特定内容,还能在应用未安装时,先将用户引导到应用商店下载安装应用,之后再自动跳转到目标内容页面。")]),e._v(" "),s("li",[e._v("优势: 提供了更灵活的体验,即使用户在点击链接时没有安装应用,安装后依然可以访问最初的目标页面。")])]),e._v(" "),s("RText",{attrs:{text:"使用场景"}}),e._v(" "),s("p",[e._v("用户点击了一个推荐或分享链接,未安装该应用时被引导至应用商店安装,安装后能够继续导航到原始推荐的页面。")]),e._v(" "),s("h3",{attrs:{id:"通用链接-universal-links"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#通用链接-universal-links"}},[e._v("#")]),e._v(" 通用链接(Universal Links)")]),e._v(" "),s("p",[e._v("功能: 用于在iOS系统中统一处理深度链接。它们可以根据用户设备上的应用状态,决定是打开应用还是加载相应的网页。即使用户没有安装应用,仍然会引导他们到网页版本。\n优势: iOS系统推荐的实现方式,无需使用自定义的 URL 方案,减少了 URL 冲突的风险。")]),e._v(" "),s("p",[e._v("示例: 点击 "),s("code",[e._v("https://example.com/profile/123")]),e._v(",如果用户安装了应用,会在应用中打开个人资料页面;如果未安装应用,则在浏览器中加载网页版本的个人资料页面。")]),e._v(" "),s("h3",{attrs:{id:"应用链接-app-links"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#应用链接-app-links"}},[e._v("#")]),e._v(" 应用链接(App Links)")]),e._v(" "),s("ul",[s("li",[e._v("功能: 用于在Android系统中实现类似于iOS通用链接的功能。根据用户的设备和应用状态,决定是否打开移动应用或网页。")]),e._v(" "),s("li",[e._v("优势: 类似于iOS通用链接的功能,在Android上提供了一种更简便的深度链接管理方式。")])]),e._v(" "),s("p",[e._v("示例:")]),e._v(" "),s("ul",[s("li",[e._v("当用户点击 https://example.com/profile/123,如果应用已安装,打开应用中的个人资料页面;如果应用未安装,打开网页。")])]),e._v(" "),s("h2",{attrs:{id:"deep-link的应用场景"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#deep-link的应用场景"}},[e._v("#")]),e._v(" Deep Link的应用场景")]),e._v(" "),s("ul",[s("li",[e._v("社交分享: 用户可以将应用中的特定内容(如文章、视频、个人资料等)分享给其他人,点击后直接进入应用的内容页面。")]),e._v(" "),s("li",[e._v("广告推广: 广告商可以使用深度链接将用户从广告引导到应用内的特定产品或优惠页面,从而提高转换率。")]),e._v(" "),s("li",[e._v("电子邮件营销: 邮件中嵌入的深度链接可以引导用户直接打开应用中的相关内容,而不需要额外的导航步骤。")])])],1)}),[],!1,null,null,null);s.default=i.exports}}]);
\ No newline at end of file
diff --git a/assets/js/19.afa8e383.js b/assets/js/19.afa8e383.js
new file mode 100644
index 00000000000..ff909256d80
--- /dev/null
+++ b/assets/js/19.afa8e383.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{338:function(t,n,s){"use strict";s.r(n);var e=s(4),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/190.aa969216.js b/assets/js/190.aa969216.js
new file mode 100644
index 00000000000..5d0f43c29cf
--- /dev/null
+++ b/assets/js/190.aa969216.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[190],{506:function(t,e,n){"use strict";n.r(e);var r=n(4),o=Object(r.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("blockquote",[t("p",[t("a",{attrs:{href:"https://developer.android.com/training/articles/keystore?hl=zh-cn",target:"_blank",rel:"noopener noreferrer"}},[this._v("Android 密钥库系统"),t("OutboundLink")],1)])]),this._v(" "),t("p",[this._v("TODO")])])}),[],!1,null,null,null);e.default=o.exports}}]);
\ No newline at end of file
diff --git a/assets/js/191.6338e2ba.js b/assets/js/191.6338e2ba.js
new file mode 100644
index 00000000000..ca82e2b2836
--- /dev/null
+++ b/assets/js/191.6338e2ba.js
@@ -0,0 +1 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[191],{508:function(e,t,s){"use strict";s.r(t);var a=s(4),r=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("div",{staticClass:"custom-block tip"},[t("p",{staticClass:"custom-block-title"},[e._v("提示")]),e._v(" "),t("p",[e._v("perfetto is a tool that lets you collect performance information from Android devices via the Android Debug Bridge (ADB). Invoke the perfetto tool using the "),t("code",[e._v("adb shell perfetto")]),e._v(" ... command. perfetto uses various sources to collect performance traces from your device, such as:")]),e._v(" "),t("ul",[t("li",[e._v("ftrace for information from the kernel")]),e._v(" "),t("li",[e._v("atrace for user-space annotation in services and apps")]),e._v(" "),t("li",[e._v("heapprofd for native memory usage information of services and apps")])]),e._v(" "),t("p",[e._v("作为客户端开发工程师, 更多的会注重在 Android 或者 iOS 客户端的优化, 下面以 Android 为主要场景, 进行说明\n更多内容参考: "),t("a",{attrs:{href:"https://developer.android.com/tools/perfetto",target:"_blank",rel:"noopener noreferrer"}},[e._v("android 官网给出的 perfetto command line 介绍"),t("OutboundLink")],1)]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://perfetto.dev/docs/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Perfetto*"),t("OutboundLink")],1),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://perfetto.dev/docs/reference/trace-config-proto",target:"_blank",rel:"noopener noreferrer"}},[e._v("Reference-Trace Config proto"),t("OutboundLink")],1)])])]),e._v(" "),t("li",[t("a",{attrs:{href:"https://perfetto.dev/docs/visualization/perfetto-ui",target:"_blank",rel:"noopener noreferrer"}},[e._v("perfetto-ui"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://developer.android.com/topic/performance/tracing",target:"_blank",rel:"noopener noreferrer"}},[e._v("android system trace 概览"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://blog.csdn.net/feelabclihu/article/details/126672666",target:"_blank",rel:"noopener noreferrer"}},[e._v("Perfetto 分析进阶-CSDN"),t("OutboundLink")],1)])])]),e._v(" "),t("h2",{attrs:{id:"custom-events"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#custom-events"}},[e._v("#")]),e._v(" custom-events")]),e._v(" "),t("ol",[t("li",[e._v("perfetto 跟 systrace 同样也支持自定义事件。 可以参考 "),t("a",{attrs:{href:"https://developer.android.com/topic/performance/tracing/custom-events?hl=zh-cn#java",target:"_blank",rel:"noopener noreferrer"}},[e._v("custom-events"),t("OutboundLink")],1)]),e._v(" "),t("li",[e._v("使用 perfetto 分析自定义事件时, 你可能需要配置 atrace, 相关的内容可见: "),t("a",{attrs:{href:"https://perfetto.dev/docs/data-sources/atrace#traceconfig",target:"_blank",rel:"noopener noreferrer"}},[e._v("ATrace: Android system and app trace events"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"trace-config"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#trace-config"}},[e._v("#")]),e._v(" trace config")]),e._v(" "),t("blockquote",[t("p",[e._v("这里给出配置的 demo 定义, 将如下内容保存到文件中, 比如 config.pbtx 然后运行脚本 "),t("code",[e._v("./record_android_trace -o