android Q /R/S/T onTopResumedActivityChanged方法解析

Android R+S+T 版本对内置应用默认授予所有权限,避免所有权限弹窗;及添加应用信息权限全部打开 路径一:路径二:如果默认所有内置和未安装应用都去掉所有权限,那最好是去掉多余的判断条件注意:此篇是所有权限弹窗,不是针对单个的权限弹窗。 阅读详情
AI摘要

在AndroidQ之后,由于支持多窗口和多显示模式,一个设备上可能有多个Activity处于Resumed状态。onTopResumedActivityChanged回调用于指示哪个Activity是当前最顶部的Resumed活动,帮助管理如相机等独家访问资源。当isTopResumedActivity为true时,Activity获得顶级恢复状态,反之则失去。此回调提供了一种在不同场景下更精确控制资源的方式。

疑问背景:

在Android Q高版本,发现经常通过events日志来看Activity生命周期的时候,经常看到如下打印:

06-27 12:02:07.091  4812  4812 I wm_on_top_resumed_gained_called: [227500858,com.android.launcher3.uioverrides.QuickstepLauncher,topStateChangedWhenResumed]
06-27 12:02:07.092  4812  4812 I wm_on_top_resumed_lost_called: [227500858,com.android.launcher3.uioverrides.QuickstepLauncher,topStateChangedWhenResumed]

即有wm_on_top_resumed_gained_called和wm_on_top_resumed_lost_called相关打印,第一次看到时候还是很疑惑这个东西到底是干啥的?resumed怎么会增加和失去?
在这里插入图片描述

疑问解答:

1、根据events log线索进行寻找
wm_on_top_resumed_gained_called一般这种tag,在代码中表现一般如下:WmOnToResumeGainedCalled
在这里插入图片描述这里可以寻找到相关的代码:

final void performTopResumedActivityChanged(boolean isTopResumedActivity, String reason) {
    onTopResumedActivityChanged(isTopResumedActivity);

    if (isTopResumedActivity) {
        EventLogTags.writeWmOnTopResumedGainedCalled(mIdent, getComponentName().getClassName(),
                reason);
    } else {
        EventLogTags.writeWmOnTopResumedLostCalled(mIdent, getComponentName().getClassName(),
                reason);
    }
}

在执行完了onTopResumedActivityChanged后进行的打印。

下面来重点看看onTopResumedActivityChanged

 /**
     * Called when activity gets or loses the top resumed position in the system.
     *
     * <p>Starting with {@link android.os.Build.VERSION_CODES#Q} multiple activities can be resumed
     * at the same time in multi-window and multi-display modes. This callback should be used
     * instead of {@link #onResume()} as an indication that the activity can try to open
     * exclusive-access devices like camera.</p>
     *
     * <p>It will always be delivered after the activity was resumed and before it is paused. In
     * some cases it might be skipped and activity can go straight from {@link #onResume()} to
     * {@link #onPause()} without receiving the top resumed state.</p>
     *
     * @param isTopResumedActivity {@code true} if it's the topmost resumed activity in the system,
     *                             {@code false} otherwise. A call with this as {@code true} will
     *                             always be followed by another one with {@code false}.
     *
     * @see #onResume()
     * @see #onPause()
     * @see #onWindowFocusChanged(boolean)
     */
    public void onTopResumedActivityChanged(boolean isTopResumedActivity) {
    }

从注释可以翻译出以下几个点:
1、在android Q以后,多个复合窗口下activity可以多个同时进行resume,即多个activity处于Resumed状态,所以只有onResume已经不能简单满足了
2、这个回调的参数isTopResumedActivity
为true就代表当前哪个activity是处于最最新进行resume的activity,也代表它是最顶部的resumed的activity
为false代表已经不是最顶部的resumed的activity了

3、app可以通过这个回调方便控制一些比如相机获取等,需要把相关资源让给把最顶部resumed的activity
总结:
简单说就是新版本android多个activity可以同时resumed状态了,比如分屏,自由窗口,多屏display等,但是一般最后最顶部resumed的activity获取用户焦点,有了这个回调就方便activity自行控制一些自己的资源释放和获取

更多实战即相关答疑,请关注公众号“千里马学框架”

Android Activity生命周期和堆栈管理的详解 Activity的生命周期 Activity是Android中的四大组件之一,也是最基本,最重要的组件,是android系统提供一个可视化的,能与用户交换的组件。 系统提供的组件,不需要用户实例化,用户也不能实例化,是系统进行回调,例如web开发的servlet也是系统提供的,和android 的其他系统组件一样。 那么不需要我们实例化我们怎么用呢,这些组件都有相同的特点就是: 1.都需要在配置文件中注册 2.都需要自定义类去继承系统的Api 3.都有自己的生命周期 那么Activity的生命周期有那些方法呢: 1.onCreate 2.onStart 3. 立即下载

相关推荐

千兆以太网 PCB 设计实战:4层板 100Ω 差分对布线,EMI 降低 6dB 实测

本文详细解析了千兆以太网 PCB 设计中的关键技术与实战经验,重点介绍了4层板上100Ω差分对的优化布线方法,通过实测数据展示了EMI降低6dB的有效方案。内容涵盖层叠设计、阻抗计算、布线技巧及EMI抑制措施,为硬件工程师提供了一套完整的高速电路设计解决方案。

weixin_29175469的博客 426

四大组件:Activity生命周期-Android12

四大组件:Activity生命周期-Android12

许浑的博客 2492

深入解析poi-tl自定义表格渲染插件中的多级子循环实现

本文深入解析了poi-tl自定义表格渲染插件中的多级子循环实现,详细介绍了其在处理复杂业务数据时的核心价值、实现原理及实战技巧。通过多级子循环机制,开发者可以高效地将层级数据结构渲染到Word表格中,显著提升代码简洁性和维护效率。文章还分享了性能优化和异常处理经验,帮助开发者更好地应用该插件。

weixin_33734785的博客 484

【Android 12】Activity启动模式

一、启动模式 google文档的介绍: 您可以通过启动模式定义 Activity 的新实例如何与当前Task关联。您可以通过两种方式定义不同的启动模式: 使用manifest文件 当您在manifest文件中声明 Activity 时,您可以指定该 Activity 在启动时如何与Task关联。 使用Intent标记 当您调用 startActivity()时,可以在 Intent中添加一个标记,用于声明新 Activity 如何(或是否)与当前Task相关联。 因此,如果 Activity A 启动 A

yihanss的博客 1840

昇腾AI处理器Ascend C编程:从C/C++基础到高性能算子开发实战

异构计算是提升AI算力效率的核心技术,通过在CPU之外引入专用处理器(如GPU、NPU)协同工作,实现大规模并行计算。其原理在于将计算密集型任务卸载到专用硬件,利用其高并行架构加速处理。技术价值在于突破传统CPU的算力瓶颈,为深度学习训练与推理提供强大动力,广泛应用于模型部署、科学计算和高性能计算场景。本文聚焦昇腾AI处理器的原生编程语言Ascend C,它基于C/C++标准扩展,通过显式内存管理和任务并行模型,充分发挥达芬奇架构中Cube与Vector单元的性能。针对CANN算子开发,文章详解了从环境搭建

weixin_34411563的博客 366

YOLO11涨点优化:小目标检测 | 多头检测器提升小目标检测精度

引入多头检测器助力YOLO11,添加一个微小物体的检测头暴力提升小目标检测性能

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 4742

Android 日志获取方法

通过 cat bugreport-star-RKQ1.201112.002-2021-04-19-15-23-40.txt | grep 'wm_' | grep 'account' 可以将account应用的 所有窗口Activity活动信息打出来: 04-19 15:23:08.291 10114 3949 3949 I wm_on_stop_called: [0,com.xiaomi.account.ui.SnsListActivity,LIFECYCLER_STOP_ACTIVITY,0] 0

ly969434341的专栏 1201

XLSX Workbench 在 ABAP 世界的定位与实战:从概念到完整示例

XLSX Workbench 在可视化、易维护与批量后台生成三方面填补了 ABAP 报表到 Excel 的空白。它与官方类及社区明星 abap2xlsx 形成了“模板驱动、代码驱动、二者兼顾”的互补格局。掌握 Workbench 后,开发者能把精力集中在业务逻辑以及数据质量,而把排版细节交给图形化工具,大幅加速交付与迭代。通过本文提供的示例,你可以立即在项目中落地并尝到效率提升的红利。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 521

应用的Activity生命周期调用后EvenetLog回调

表示Activity的onResume被调用完成.Android R变更为:wm_on_resume_called (之前am_on_resume_called )Android R变更为:wm_on_create_called(之前am_on_create_called)表示Activity的onTopResumedActivityChanged(true)被调用完成.表示Activity的 onCreate被调用完成,即APP中的onCreate调用完成。表示Activity的onStop被调用完成.

吉吉的博客 3029

【UG\NX二次开发】使用内部函数展开和折叠工序导航器

NX二次开发-群精选」专栏收录了那些曾散落在聊天对话框里的精彩的知识分享,这都是被遗落的宝贵财富。让我们一起向大佬学习,充满激情地进步,不断超越自己。底部联系方式,欢迎您加入一起交流。​下次一定。

王牌飞行员_里海的博客 820

SPMI协议学习总结

SPMI(System Power Management Interface)是由MIPI(Mobile Industry Processor Interface)联盟定义的一种硬件接口标准,它主要用于移动设备中,连接SoC(System on Chip)处理器系统的集成电源控制器与一个或多个电源管理IC(PMIC),以实现精确的电源管理

歌颂苦难的行为是无耻的; 1082

Activity窗口的添加过程

主要回调onResume之后执行makeVisible(),最终调用到。

许浑的博客 736

位置点位到达判断FC(Easy+Codesys+博途平台)

IN rActPositon REAL 轴当前实际位置 1IN arAbsPosition REAL[10] 各工作点位坐标 2IN rDeadZone REAL 位置达到判断域值 范围 3OUT abInAbsPos BOOL[10] 到达各绝对定位点位标志 位置到达输出 4VAR i INT 循环计数 5VAR rErr REAL 位置偏差 6。

RXXW_Dor的博客 536

Android Activity生命周期搬运与理解

Android Activity生命周期搬运与理解 导读 众所周知Android的Activity生命周期设计从OnCreate开始到OnDestroy完结,那设计Activity的工程师为何要做出这样的设计,每个生命周期方法的意义又是什么呢?知其然,且知其所以然,才能更好帮助我们写出更优秀的代码,今天再次聊聊他们的意义,如你有高见,请在评论区留言 Activity各个生命周期方法 onCr...

jackzhouyu的专栏 1056

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Android 锁屏状态下启动应用很慢的原因分析

最近在工作中遇到一个需求就是,在锁屏状态下直接拨打电话,功能实现之后测试给的反馈是操作之后到电话拨出的时间太长(大概5秒)。希望能优化一下。后来经过分析确定不是应用层的问题。然后就一顿百度、Google,发现了一篇文章专门在分析这个问题。我也是看了人家写的才准备照着这篇文章的思路分析一下源码。首先声明一下,我写的这篇文章是为了记录此问题分析的一个过程,其源码是基于Android 11(Api 30)。 话不多说,现在开始。。。 拨打电话启动的action为android.intent.action.CA

小小时光 3770

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Caused by: java.lang.IllegalArgumentException: Receiver not registered

或许是没走onCreate,但是Resume一定走的,那么就是Destroy的时候,为什么receiver非空,因为取消注册的时候是不会置为空的?运行时错误,在界面销毁的时候无法取消监听,因为接收器没有注册。系统强制关闭crash的应用。出现ANR,关闭应用界面。具体的代码类和方法行数。显示crash 弹窗。

。 1072

Android 应用冷启动event log

位于 com/android/server/wm/ActivityTaskSupervisor.java 中的 realStartActivityLocked 意味着真正 的要去client端去启动一个activity。发生在给clent端发送ResumeActivityItem之后并设置相应的ActivityRecord的状态为 RESUMED之后.发生在wms计算出新的焦点窗口后把窗口焦点窗口信息发送给sf的时刻.activity的onCreate被调用后调用。

qq_41095045的博客 1222

android日志系统详解

在framework开发过程中,日志是必不可少的一个调试手段。Android通过LOGD、SLOGD和EventLog等方式进行日志的打点。但是日志是如何写入和读取的?开启android日志系统之旅。

allen_xu_2012_new的博客 4788

Framework层分析按下返回键退出桌面流程

将Home stack移到前台并开始pause app的Activity 04-12 11:18:06.601 1851 4006 I wm_finish_activity: [0,251368919,44,com.miui.gallery/.activity.HomePageActivity,app-request] 04-12 11:18:06.615 1851 4006 I wm_focused_stack: [0,0,1,44,finish-top adjustFocusToNextFocusab

xiaoyantan的博客 2009

Android 系统日志关键字

Android 系统日志关键字

许浑的博客 3563

Activity生命周期递归问题查看

这类问题一般比较难分析,符合以下情况的才有可能分析出来: 能够复现并调试 有问题时的堆栈以及对应的event log TaskFragment#shouldSleepActivities 方法导致递归 There is a recursion among check for sleep and complete pause during sleeping 关键log 01-08 08:45:42.946 1941 5167 I wm_finish_activity: [0,240239432,518

xiaoyantan的博客 998

折叠屏适配

安卓折叠屏幕是利用了全新的柔性屏技术,可实现屏幕的弯曲和折叠。折叠屏手机通常有一个折页或者铰链,将两个显示屏分开,带有铰链的设备可以在铰链后面跨越内容,比如微软Surface的跨接模式。有些设备可以半折叠或者其他姿势放置,比如三星的Galaxy Z Flip是翻盖式设备,支持折叠和部分折叠状态。......

york2017的博客 9558

TopResumedActivityChangeItem

TopResumedActivityChangeItem 当TopResumedActivity改变的时候就会送该消息 prev.setState(PAUSING, "startPausingLocked"); task.onActivityStateChanged(this, state, reason); 1 task.setResumedActivity(ActivityRecord r, String reason) mResumedActivi

jieliaoyuan8279的博客 5622

安卓疑难问题冻屏/黑屏深入剖析原因-全网独家framework实战

明显可以看出来这里正常情况有相关的finishRecentsAnimation操作,但是异常情况下没有finishRecentsAnimation,这个其实也可以判断出来异常冻屏的本质原因是因为没有进行相关的finishRecentsAnimation操作,即相当于动画在执行,但是因为某些异常没有得到良好收尾操作,从而导致问题。其实TaskBar的隐藏本身系统中有更好的方法,不应该自己做的这种隐藏TaskBar的主View即mDragLayer方法,完全可以源头 上进行规避。

liaosongmao1的专栏 549

【Android 源码分析】Activity生命周期之onDestroy

ActivityThread::performDestroyActivity -- onDestroy流程WindowManagerImpl::removeViewImmediate -- UI处理ActivityClient::activityDestroyed -- SystemService 进程处理。

隔壁小王的博客 2946

Configuration Change派发到App进程

其它Activity会在下次resume的时候再触发relaunch,跟上面两个不在同一线程以及同一时间执行,如果想查找relaunch的具体原因,需要向前时间查找对应的configuration_changed的log,具体参考https://blog.youkuaiyun.com/xiaoyantan/article/details/126292133。针对Activity级别的处理,relaunch当前Activity或触发当前Actiivty回调onConfigurationChanged方法,只会发生其一。

xiaoyantan的博客 1308
上一篇: android framework实战开发之WINDOWING_MODE_FREEFORM自由窗口相关
下一篇: pip触摸部分源码分析-pip窗口的移动,删除窗口/车载车机手机系统开发
千里马学框架
博客等级 码龄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、付费专栏及课程。

余额充值