系统app开发之桌面调试Launcher3 Dumpsys信息解析

Android 进阶——Framework 核心之dumpsys命令浅析 Dumpsys是安卓系统提供用来动态查看系统内部服务运行状态的命令。了解dumpsys命令的使用方法,可以方便我们查看系统中各个进程内存使用情况,各个进程CPU占用率情况,各个应用apk运行情况,系统唤醒源情况等。 阅读详情

系统app开发调试方式

平时我们都是使用dumpsys来输出某个服务的相关信息,比如dumpsys SurfaceFlinger,dumpsys window windows等。

这些其实都是系统的service情况信息输出,但是大家是否有想过我们普通的app想要进行dump应该如何呢?比如我想要在查看调试自己写的Activity相关的信息如何查看呢?

这个就是我们今天要来分享的一个dump app的相关相关信息方式。

dump命令使用

命令格式

Activity的dump方式
dumpsys activity xxxx(Activity类名)

这里的xxxx最好写出全类名。

在这里插入图片描述

Service的dump方式

比如要dump Launcher的某个service那么格式如下:

adb shell dumpsys activity service xxx(某个Service名字)
案例:

adb shell dumpsys activity service TouchInteractionService
或者
 adb shell dumpsys activity service com.android.launcher3/com.android.quickstep.TouchInteractionService
这些Activity名字和Service名字哪里获取呢?

可以使用dumpsys package xxx包名。

比如桌面有哪些Activity和Service

adb shell dumpsys package com.android.launcher3

在这里插入图片描述

本文基于 adb shell dumpsys activity QuickstepLauncher 命令的输出,结合 AOSP16-r4 Launcher3
源码,逐段解析每个 dump 信息的作用和调试价值。


1. Activity 生命周期与状态 (ActivityRecord)

TASK null id=23 userId=0 displayId=0(type=INTERNAL)
  ACTIVITY com.android.launcher3/.uioverrides.QuickstepLauncher 5bb04f pid=1382 userId=0 uid=10122 displayId=0(type=INTERNAL)
    Local Activity 869e2cf State:
      mResumed=true mStopped=false mFinished=false
      mIsInMultiWindowMode=false mIsInPictureInPictureMode=false
      mChangingConfigurations=false
      mCurrentConfig={1.0 310mcc260mnc [en_US] ldltr sw360dp w360dp h640dp 480dpi nrml long compactNeeded port ...}
      mLoadersStarted=true

来源:Android 框架层 ActivityRecord.dump()(系统侧 dump,非 Launcher 自己控制)。

各字段含义:

字段含义调试场景
TASK null id=23Task ID 为 23,null 表示没有关联的 Task 对象引用Activity 任务栈跟踪
userId=0运行在系统用户 (Owner)多用户问题排查
displayId=0运行在内置主屏幕 (DEFAULT_DISPLAY)多屏/外接显示器排查
pid=1382Launcher 进程 PID进程存活/CPU 占用排查
uid=10122Launcher 应用 UID权限问题排查
mResumed=trueActivity 处于 Resumed 状态(前台可见可交互)Launcher 是否在前台
mStopped=falseActivity 未被停止onStop() 是否调用
mFinished=falseActivity 未结束是否正在退出
mIsInMultiWindowMode=false未处于多窗口/分屏模式多窗口适配问题
mIsInPictureInPictureMode=false未处于画中画PiP 行为排查
mChangingConfigurations=false未正在处理配置变更配置变更卡死排查
mCurrentConfig当前 Configuration 完整快照屏幕密度/语言/屏幕尺寸异常
mLoadersStarted=trueLoader 已启动(数据加载或 ContentProvider 就绪)数据加载时序问题

调试价值:这是第一个要看的区域。如果 Launcher 行为异常,先确认它是否处于预期生命周期状态。

相关源码:

// QuickstepLauncher.java 继承自 Launcher extends BaseActivity
// 生命周期回调在 Launcher.java 中:
// onResume() -> onPause() -> onStop() -> onDestroy()
// 以及 onActivityFlagsChanged() 处理状态标志变化

2. ViewRoot 渲染系统

其实这部分数据就是把我们熟悉的ViewRootImpl.java相关的数据进行输出。

ViewRoot:
  mAdded=true mRemoved=false mStopped=false
  mPausedForTransition=false
  mConsumeBatchedInputScheduled=false
  mPendingInputEventCount=0
  mTraversalScheduled=false
  mReportNextDraw=false

来源:ViewRootImpl.dump(),是每个 Window 的顶层渲染管理器。

各字段含义:

字段含义调试场景
mAdded=trueViewRoot 已添加到 WindowManagerWindow 是否成功添加
mRemoved=false未被移除Window 泄漏排查
mStopped=false未停止Window 是否可见
mPausedForTransition=false未因转场动画暂停渲染转场动画卡顿排查
mPendingInputEventCount=0无待处理输入事件输入事件积压排查
mTraversalScheduled=false无待执行的 measure/layout/drawUI 是否空闲
mReportNextDraw=false不需要报告下一次绘制绘制完成通知

调试价值:用于诊断 UI 渲染问题。如果 mTraversalScheduled=true 且长时间不变,
说明可能发生了 measure/layout 死循环或阻塞。

相关源码:

// QuickstepLauncher.java: onCreate()
getWindow().addPrivateFlags(PRIVATE_FLAG_OPTIMIZE_MEASURE);
// PRIVATE_FLAG_OPTIMIZE_MEASURE 优化 measure 过程,减少过度测量

2.1 app层收到事件处理理

android.view.ViewRootImpl$NativePreImeInputStage: mQueueLength=0
android.view.ViewRootImpl$ImeInputStage: mQueueLength=0
android.view.ViewRootImpl$NativePostImeInputStage: mQueueLength=0

含义:三阶段输入管道队列长度均为 0,说明当前没有积压的输入事件。

2.2 Configuration 报告

mLastReportedMergedConfiguration={mGlobalConfig=... mOverrideConfig=...}
mLastConfigurationFromResources={...}

含义:最后一次报告的全局配置与 Override 配置。mOverrideConfig 中
mActivityType=home 表示这是 Home Activity。


3. InsetsController — 窗口边距

InsetsController:
  mDisplayFrame=Rect(0, 0 - 1080, 1920)
  InsetsSource id=d1660001 type=navigationBars frame=[0,1848][1080,1920] visible=true
  InsetsSource id=d6d50000 type=statusBars frame=[0,0][1080,72] visible=true
  InsetsSource id=3 type=ime frame=[0,0][0,0] visible=false

来源:InsetsController.dump(),管理系统栏(状态栏、导航栏、输入法)对窗口的边距影响。

关键条目解读:

条目含义
navigationBars [0,1848][1080,1920]导航栏占据底部 72px(1920-1848),在 y=[1848,1920]
systemGestures [0,0][90,1920]左侧 90px 是系统手势区域(返回手势)
systemGestures [990,0][1080,1920]右侧 90px 是系统手势区域
statusBars [0,0][1080,72]状态栏占据顶部 72px
mandatorySystemGestures [0,1824][1080,1920]底部 96px 强制手势区域(保留区)
ime frame=[0,0][0,0] visible=false输入法未弹出(大小为 0)

调试价值:

  • 确认设备是手势导航还是三键导航(有 systemGestures 区域 = 手势导航)
  • 排查内容被系统栏遮挡的问题
  • 确认 IME 弹出/收起状态

4. View Hierarchy — 视图树(最核心)

平时要看View的层级都是需要通过布局抓取工具等来查看,那么这个dump方式也算是最简单的方式来获取。

com.android.internal.policy.DecorView{9104c85}[QuickstepLauncher]
  android.widget.LinearLayout
    android.widget.FrameLayout #1020002 android:id/content
      com.android.launcher3.LauncherRootView #7f0901e3 app:id/launcher
        com.android.launcher3.dragndrop.DragLayer #7f090144 app:id/drag_layer
          com.android.launcher3.views.AccessibilityActionsView
          com.android.launcher3.Workspace #7f090409 app:id/workspace
            com.android.launcher3.CellLayout
              ShortcutAndWidgetContainer
                QsbContainerView #7f0902ef app:id/search_container_workspace
                  ...
          com.android.launcher3.Hotseat #7f0901b4 app:id/hotseat
            DoubleShadowBubbleTextView (4 icons)
          PageIndicator (page_indicator_container)
          DropTargetBar #7f090146 (drop_target_bar)
          ScrimView #7f0902dd (scrim_view)
          LauncherRecentsView #7f090282 (overview_panel)
          OverviewActionsView #7f090281
          LauncherAllAppsContainerView #7f090098 (apps_view)

含义:完整的 View 层级结构,展示了从 DecorView 到每个子 View 的树状关系。

下面图这个桌面的view展示情况就可以与上面布局完全匹配,偶尔需要自己模拟触摸事件,或者说让ai来模拟点击测试时候,如果ai不知道如何获取控件坐标也可以提醒使用这种dump方式。
在这里插入图片描述

关键视图与源码对应:

View 类作用
LauncherRootViewLauncher 的根 ViewGroup
DragLayer拖拽事件分发层,所有 TouchController 在此注册
Workspace主屏幕工作区,包含 CellLayout 页面
CellLayout单个主屏幕页面,管理图标/Widget 网格布局
QsbContainerView搜索框容器(Quick Search Box)
Hotseat底部固定快捷栏(Hotseat)
PageIndicator页面指示器(圆点)
DropTargetBar拖拽目标区域(删除/卸载)
ScrimView模糊/暗色遮罩层
LauncherRecentsView最近任务概览视图(Overview)
OverviewActionsView概览页操作按钮(截图、分屏)
LauncherAllAppsContainerView所有应用列表视图
PredictionRowView应用预测行

相关源码:

// QuickstepLauncher.java: setupViews()
mActionsView = findViewById(R.id.overview_actions_view);
RecentsView overviewPanel = getOverviewPanel();
overviewPanel.init(mActionsView, mSplitSelectStateController, ...);

// Launcher.java: setupViews()
mDragLayer = findViewById(R.id.drag_layer);
mWorkspace = mDragLayer.findViewById(R.id.workspace);

调试价值:这是最重要的调试区域之一:

  • 检查 View 是否被正确添加到层级中
  • 通过 V.E...... 等标志查看 View 的 visibility 和 enable 状态
  • G.ED..... 中 G = GONE, I = INVISIBLE
  • 确认视图树结构是否符合预期

如何Activity等dump中加入自定义信息

这个其实Activity,Service等类本身自带了相关的dump方法:

我们只需在自己Activity方法中进行重写dump,然后加入自己的一些自定义想要dump东西
在这里插入图片描述
原文地址,更多fw干货获取:
https://mp.weixin.qq.com/s/jufOkfC_OlJqd1U9NyuTYw

Android Launcher启动过程深度解析:从系统就绪到首帧渲染 Launcher是Android系统中承载用户交互入口的核心Activity组件,其启动并非简单Intent触发,而是由ActivityManagerService在systemReady后主动调度的系统级行为。理解其基于MAIN+HOME intent-filter的识别机制、AMS-PMS-WMS三重校验流程,以及进程级与Activity级双重生命周期,对解决冷启动卡顿、桌面图标异常、Home键失效等典型问题至关重要。结合Systrace性能分析、Logcat精准过滤和AOSP源码调试,开发者可定位从A 阅读详情

相关推荐

深入解析Android TV应用不显示桌面图标的背后机制

本文深入解析了Android TV应用不显示桌面图标的背后机制,重点介绍了CATEGORY_LEANBACK_LAUNCHER这一关键Intent的作用。通过对比普通手机应用和TV应用的不同配置,详细说明了系统如何筛选显示应用,并提供了调试验证技巧和最佳实践,帮助开发者解决TV应用显示问题。

weixin_33676492的博客 464

dumpsys 命令使用

dumpsys 常用操作以及实现的来龙去脉. 一,常用操作: 1,在Activity中,可重写dump函数,实现打印,可通过如下命令获取输出:adb shell dumpsys activity <activity_component_name>2,在Service的子类中,可重写dump函数,使用如下命令实现命令输出:adb shell dumpsys activity service <yo

hailushijie的专栏 4564

Android Launcher启动原理:从systemReady到首帧渲染全链路解析

Launcher是Android系统中首个且最关键的Activity,其启动并非普通App流程,而是系统服务就绪后由ActivityManagerService(AMS)触发的基础设施级调度。它依赖PackageManagerService(PMS)完成组件解析、Intent匹配与资格校验,经Zygote进程孵化、Application创建、Activity生命周期激活等多层协作,最终抵达onResume与首帧渲染。该过程深度耦合AMS、PMS、WMS及Zygote四大核心模块,既是Android应用生命周

weixin_33796177的博客 372

android dumpsys 快速入门

dumpsys属于android平台上的一个bin文件,放置在/system/bin 下面,主要完成打印系统服务的信息,帮助调试分析解决问题。之前写的文章太长,感觉很难坚持看完,那么后续在写文章的时候,尽量讲的快一些,内容精简一些。使用dumpsys -l 显示出来当前的服务列表。我平时关注的是 surfaceflinger activity input``window,因此可以通过 dumpsys

程序员入门进阶 936

Android开机自启与霸屏启动:从BOOT_COMPLETED到系统Launcher的完整指南

在Android应用开发中,开机自启动是一个常见但复杂的工程需求,尤其在信息发布终端、工业控制设备等场景中,实现应用开机后自动运行并全屏显示(即“霸屏”)至关重要。其核心原理涉及Android系统的应用启动层次与权限机制,从普通应用层到系统应用层,不同层级拥有不同的能力边界。普通应用通过BroadcastReceiver监听BOOT_COMPLETED广播实现自启,但受Android版本迭代(如Android 8.0的后台限制、Android 10的Activity启动限制)和厂商ROM定制的影响,稳定性面

weixin_33806914的博客 370

大麦盒子DM4036折腾全攻略:当贝桌面安装与三网通用DNS设置

ADB(Android Debug Bridge)是连接电脑与安卓设备的官方调试工具,能够高效完成应用安装、系统参数修改等操作;DNS(域名解析系统)则决定了设备访问网络服务的速度与稳定性。对于采用海思hi3798mv100芯片的运营商定制机顶盒,原厂固件往往限制用户自定义能力,导致系统卡顿、视频加载缓慢。通过ADB技术,用户可以安全地安装当贝桌面等第三方启动器,绕过原厂桌面的资源占用;同时配置阿里DNS、腾讯DNS等公共域名服务器,可显著提升解析效率与播放流畅度。这类优化尤其适合大麦盒子DM4036等非高

weixin_34332905的博客 411

android framework系统源码分析之dumpsys原理分析-千里马带你学framework

背景: hi,粉丝朋友们大家好! 我们学习android framework实战开发过程中经常会用到一些辅助的shell命令,比如最经典就是我们常见的dumpsys啦,还记我给大家讲解的入门课,实战课,跨进程专题课其实都用用到这个命令;当时我只是给大家讲解怎么使用这种dumpsys一些命令,并没有给大家讲解它的一个原理,但是对于对android系统充满好奇小伙伴们,肯定不满足与简单使用,还是想搞明白他到到底什么原理,那么搞懂它到底有什么好处么?那当然是好处多多,我这里给大家主要罗列一下几点: 1、分析出du

liaosongmao1的专栏 1151

Android系统启动流程完全指南:从电源键到桌面

操作系统从硬件上电到用户界面就绪,期间要经过固件引导、内核初始化、系统服务启动等多个环节。Android作为移动操作系统,其启动流程在通用机制之上引入了独特的进程孵化与系统服务管理方式,例如Zygote作为应用进程孵化器,SystemServer集中管理核心服务。理解这套流程,不仅有助于优化开机速度、定位反复重启或卡在开机动画等异常,更是系统定制、设备移植和车机开发中的工程基础。本文从底层Bootloader到Linux内核,再到init进程、Zygote和SystemServer,最后到Launcher显

weixin_34115824的博客 373

dumpsys命令用法

dumpsys命令功能很强大,能dump系统服务的各种状态,非常有必要熟悉该命令的用法以及含义。 一、 dumpsys命令 1.1 服务列表 不同的Android系统版本支持的命令有所不同,可通过下面命令查看当前手机所支持的dump服务,先进入adb shell,再执行如下命令:dumpsys -l。 这些服务名或许你并看不出其调用的哪个服务,那么这时可以通过下面指令:service l

Android系统攻城狮 7796

DiLink 4.0车机ADB调试实战:不Root的深度诊断方法

ADB调试是Android系统基础运维能力,其核心原理在于通过USB协议建立主机与设备间的命令通道,实现进程控制、日志采集与服务状态查询。在车规级系统中,ADB的技术价值从开发者工具升维为安全可控的远程诊断探针——既需遵循SELinux策略与分区只读等车载加固机制,又必须适配硬件级USB握手、动态日志缓冲、车规休眠唤醒等特殊约束。典型应用场景包括车机黑屏定位、第三方APP兼容性分析、OTA升级失败溯源及传感器异常诊断。本文聚焦比亚迪DiLink 4.0平台,详解dumpsys、logcat、am/pm、in

weixin_33984032的博客 342

TCL雷鸟电视ADB调试指南:安全卸载预装应用与系统优化

Android Debug Bridge(ADB)是安卓系统提供的核心调试工具,它允许开发者通过命令行与设备进行通信,实现对应用的安装、卸载、调试和系统状态监控。在智能电视领域,ADB技术为用户提供了超越图形界面的深度控制能力,尤其适用于管理厂商预装应用。通过开启电视的开发者选项和网络ADB调试,用户可以在同一局域网内从电脑端安全地停用或卸载非必要的系统应用,从而提升设备运行效率、释放存储空间并减少广告干扰。这一技术方案平衡了系统安全性与用户自主权,广泛应用于智能电视、机顶盒等安卓设备的个性化优化场景,例如

weixin_30561177的博客 618

保姆级教程:在Android 13源码中修改Launcher3默认桌面布局(附5x5布局文件详解)

本文提供了一份详细的Android 13源码中修改Launcher3默认桌面布局的教程,特别解析了5x5布局文件的配置与修改技巧。从Launcher3布局系统架构到高级调试方法,帮助开发者深度定制Android桌面,提升用户体验。

Dendy之Java小屋 447

Android 系统启动过程

本文完整拆解 Android 从按下电源键到桌面出现的七阶段启动链路,涵盖 BootROM、BootLoader、Linux Kernel、init、Zygote、SystemServer 及 Launcher 各阶段的核心职责与耗时分解。提供 preload 裁剪、服务延迟启动、bootchart 分析等开机优化实战,以及卡 Logo 问题的串口与 logcat 调试方法。

weixin_44081096的博客 646

Android Launcher启动全流程解析:从Zygote到桌面渲染

Launcher是Android系统中承载所有App入口的核心Home Activity,其启动过程本质是系统服务就绪后首个跨进程Activity调度的完整链路。它依赖Zygote进程孵化机制实现类预加载与内存共享,通过Binder与ActivityManagerService、PackageManagerService、WindowManagerService等关键系统服务完成三次握手式绑定,并基于Intent匹配规则扫描并构建桌面图标列表。该流程直接决定冷启动性能、图标可见性与点击响应性,广泛应用于RO

weixin_34268310的博客 750

Android动态更换桌面图标:Activity-alias与PackageManager原理及实践

桌面图标是Launcher对应用入口组件的可视化表示,并非静态文件。Android未提供运行时直接修改图标资源的接口,但通过Activity-alias预先声明多个入口别名,再借助PackageManager的setComponentEnabledSetting切换组件启用状态,即可实现动态更换图标。这种方式本质是替换入口,系统持久化组件状态,重启后依然生效。该技术广泛应用于节日运营、版本营销等场景,也是开发者规避Manifest不可变限制的标准方案。本文从Launcher解析机制讲起,分析Activity

weixin_33874713的博客 309

AI测试实战:用文心一言5分钟生成登录功能测试用例(附Excel模板)

本文详细介绍了如何利用AI工具(如文心一言)在5分钟内高效生成登录功能测试用例,并提供了可直接应用的Excel模板。通过对比传统手工编写与AI生成的效率差异,展示了AI在软件测试领域的巨大优势,包括减少重复劳动、避免边界条件遗漏和提升格式标准化。文章还包含实战技巧、高级应用方案和行业最佳实践,助力测试人员快速提升工作效率。

weixin_30379531的博客 410

Android系统启动流程全解析:从电源键到Launcher的完整链路

从按下电源键到桌面出现,Android设备要经历BootROM、Bootloader、Linux内核、init进程、Zygote、SystemServer等多级接力。理解这套启动流程,是进行系统定制、开机优化和异常排障的基础。文章从Linux内核如何启动init进程讲起,梳理属性系统、SELinux、Binder等关键机制,并介绍如何通过dmesg、ps、getprop等工具定位启动卡点。无论是优化开机速度,还是解决Framework启动异常,掌握这条完整链路都能帮助工程师快速缩小问题范围,提高开发效率。最

weixin_33898876的博客 322

Zynq UltraScale+网络加速方案:用AXI Ethernet Subsystem实现2.5G吞吐量的配置秘籍

本文详细介绍了在Xilinx Zynq UltraScale+平台上使用AXI Ethernet Subsystem实现2.5Gbps网络吞吐量的配置方法。通过硬件设计优化、Vivado工程配置、Linux驱动调优及性能测试等关键步骤,为工业视觉和5G前传等高速网络应用提供可靠解决方案。

weixin_30485379的博客 614

Android桌面图标隐藏全解析:从静态配置到动态显隐与ADB调试

Android应用开发中,通过AndroidManifest配置Intent-Filter可控制桌面图标显隐,其原理是系统根据CATEGORY_LAUNCHER声明识别启动入口。动态方案则利用PackageManager.setComponentEnabledSetting在运行时切换组件状态,实现图标隐藏与恢复,技术价值在于平衡隐蔽性与可用性。常见于企业工具、辅助服务等场景,需结合ADB命令验证状态并处理国产ROM兼容性。本文深入探讨从基础配置到进阶技巧的完整实现链路,涵盖动态显隐、替代入口设计及多版本适

weixin_33859231的博客 251

基于STM32平衡小车设计

随着智能硬件的发展,基于STM32的两轮智能平衡车作为一种新型的智能移动工具,具备较高的应用价值。本文旨在设计并实现一款基于STM32微控制器的智能平衡车系统,提升其稳定性和操控性,探索如何通过传感器数据和控制算法实现精确平衡控制。 本设计基于STM32微控制器,选择了STM32F103系列作为核心控制器,具有足够的处理能力和丰富的外设接口。系统通过MPU6050传感器获取三轴加速度和三轴陀螺仪数据,实现实时姿态检测。电机驱动部分采用合适的驱动模块,能够控制两个直流电机,并支持PWM调速。设计中还包括OL

m0_74026776的博客 2730

Cesium高效渲染海量GeoJSON数据的7种优化策略与实战解析

本文深入解析Cesium高效渲染海量GeoJSON数据的7种优化策略,包括瓦片化转换、LOD分级加载、数据简化等关键技术。通过实战案例展示如何解决渲染卡顿问题,提升矢量数据加载性能,实现流畅的60FPS交互体验。特别针对GeoJSON大数据量场景提供完整优化方案。

h0i1j2k3l的博客 934

Android AudioFlinger驱动调试日志全解析

AudioFlinger(AF)是Android音频系统的核心服务,负责音频流调度、混音、设备路由与HAL交互。其日志并非普通应用日志,而是融合了用户态服务逻辑、实时buffer状态、硬件抽象层(HAL)反馈及音频策略决策的复合型系统日志。理解AF日志需掌握其分层设计原理:上承App音频请求(Track生命周期、Session ID、PID/TID),中控Policy路由与资源抢占,下接HAL设备打开/写入/错误码(如ENODEV、ETIMEDOUT)。技术价值在于实现‘可定位、可复现、可归因’的深度问题诊

weixin_34326179的博客 465

OpenClaw进阶实战(二十一):工作流6:跨平台舆情监控与自动响应

摘要: 本文介绍基于OpenClaw构建自动化舆情监控系统,实现多平台数据采集、AI情感分析与智能预警。系统架构包含数据采集(微博/小红书/抖音)、消息队列、情感分析(SnowNLP/大模型API)、分级预警和自动响应模块。通过技能化开发(如微博API采集、小红书模拟登录)实现7×24小时监控,结合情感强度与传播速度分级处理负面舆情,形成"采集-分析-预警-处置"闭环,适用于企业私有化部署。

PeterPan的博客 299
上一篇: aosp新增窗口层级 Type 完整实现方案(有源码)-wms需求和面试题
下一篇: 深入剖析安卓布局uiautomator抓取工具原理
千里马学框架
博客等级 码龄6年 1万+粉丝 650原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值