android 13 systrace/perfetto视角分析SurfaceFlinger中截图源码分析

android trace —— 简介,适合新人 systrace的简单介绍、抓取trace方法、简单分析trace内容,非常适合新人 阅读详情
AI摘要

本文详细解析了Android截图功能的实现原理,重点关注了adbshell命令行方式下的screencap命令,并通过perfettotrace分析了截图背后的跨进程调用过程,涉及SurfaceFlinger和SurfaceComposerClient的核心接口。

背景:

截图是一种开发过程中经常遇到的功能,但是这个功能底层是怎么实现的?今天就来给大家分享一下的,截图的的实现原理。
截图场景:
一般截图都有以下几个方式:
1、音量下键+power
2、systemui中下拉状态栏,或者关机选着界面
3、adb shell命令行方式screencap命令方式

主要就是以上几个,虽然场景不一样,但是他们最后调用的截图接口其实都是同一个,都是最后会调用到surfaceflinger中的截图方法,下面就以adb shell命令行方式screencap案例分析,因为他的接口调用最为简单,这次分析方式主要是使用perfetto的trace分析方式

screencap命令相关源码及抓取perfetto操作

抓取perfetto方式:

1、输入如下命令进行perfetto抓取

test@test:~$ aosp/external/perfetto/tools/record_android_trace -o $(date +%Y%m%d_%H%M%S)_trace_file.perfetto-trace -t 5s -b 32mb sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory gfx view wm am ss video camera hal res sync idle binder_driver binder_lock ss

2、另一个终端输入如下命令进行截图:

screencap -p /sdcard/1.png

代码位置:

frameworks/base/cmds/screencap/screencap.cpp

int main(int argc, char** argv)
{
    std::optional<DisplayId> displayId = SurfaceComposerClient::getInternalDisplayId();
   //省略部分
    ProcessState::self()->setThreadPoolMaxThreadCount(0);
    ProcessState::self()->startThreadPool();

    sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
    //最为核心的方法ScreenshotClient::captureDisplay
    status_t result = ScreenshotClient::captureDisplay(*displayId, captureListener);
    if (result != NO_ERROR) {
        close(fd);
        return 1;
    }

    ScreenCaptureResults captureResults = captureListener->waitForResults();
    if (captureResults.result != NO_ERROR) {
        close(fd);
        return 1;
    }
    ui::Dataspace dataspace = captureResults.capturedDataspace;
    sp<GraphicBuffer> buffer = captureResults.buffer;

    result = buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);


    if (png) {
        AndroidBitmapInfo info;
        info.format = flinger2bitmapFormat(buffer->getPixelFormat());
        info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
        info.width = buffer->getWidth();
        info.height = buffer->getHeight();
        info.stride = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat());

        int result = AndroidBitmap_compress(&info, static_cast<int32_t>(dataspace), base,
                                            ANDROID_BITMAP_COMPRESS_FORMAT_PNG, 100, &fd,
                                            [](void* fdPtr, const void* data, size_t size) -> bool {
                                                int bytesWritten = write(*static_cast<int*>(fdPtr),
                                                                         data, size);
                                                return bytesWritten == size;
                                            });
    
   //省略部分

        if (fn != NULL) {
            notifyMediaScanner(fn);
        }
    }
     
   //省略部分
    return 0;
}

其实整个screencap最为核心代码就是只有一句:
ScreenshotClient::captureDisplay
这个就是调用截图相关的接口,该接口实现如下:

status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs,
                                          const sp<IScreenCaptureListener>& captureListener) {
    sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService());
    if (s == nullptr) return NO_INIT;

    binder::Status status = s->captureDisplay(captureArgs, captureListener);
    return status.transactionError();
}

其实本质是个跨进程调用,最后会调用到surfaceflinger的captureDisplay方法:

status_t SurfaceFlinger::captureDisplay(DisplayId displayId,
                                        const sp<IScreenCaptureListener>& captureListener) {
    ui::LayerStack layerStack;
    wp<const DisplayDevice> displayWeak;
    ui::Size size;
    ui::Dataspace dataspace;
    {
        Mutex::Autolock lock(mStateLock);

        const auto display = getDisplayDeviceLocked(displayId);
        if (!display) {
            return NAME_NOT_FOUND;
        }

        displayWeak = display;
        layerStack = display->getLayerStack();
        size = display->getLayerStackSpaceRect().getSize();

        dataspace =
                pickDataspaceFromColorMode(display->getCompositionDisplay()->getState().colorMode);
    }

    RenderAreaFuture renderAreaFuture = ftl::defer([=] {
        return DisplayRenderArea::create(displayWeak, Rect(), size, dataspace,
                                         false /* useIdentityTransform */,
                                         false /* captureSecureLayers */);
    });

    auto traverseLayers = [this, layerStack](const LayerVector::Visitor& visitor) {
        traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, visitor);
    };


    auto future = captureScreenCommon(std::move(renderAreaFuture), traverseLayers, size,
                                      ui::PixelFormat::RGBA_8888, kAllowProtected, kGrayscale,
                                      captureListener);
    return fenceStatus(future.get());
}
结合trace分析

具体上面的流程进行systrace、perfetto展示如下:
在这里插入图片描述
这里显示发起了一个跨进程调用,目标段是surfaceflinger进程
在这里插入图片描述trace的总结图如下:

在这里插入图片描述surfaceflinger还有一个额外的回调客户端操作:
在这里插入图片描述

1、准备好buffer来绘制截图
2、主导surfaceflinger需要相关的layer预处理
3、使用SkiaGl引擎进行进行相关的Layer绘制到新buffer
4、通知客户端,回调listener

更多干货手把手教学framework视频内容可以关注公众号或者b站up主(千里马学框架)
https://blog.youkuaiyun.com/learnframework/article/details/132739059
在这里插入图片描述

Android逆向安全-无侵入找关键call之trace日志分析大法 标题 找关键call是逆向的基本技能和分析目标,找到关键call后便可以进一步利用。在安卓App的逆向分析中,人肉逆向分析虽说不难,但是繁琐,特别是现在App体积动辄几十MB甚至几百MB,反编译出的jar或者smali文件相当多,找关键call无疑是大海捞针。 那么有什么方法可以快速找关键call呢? 之前介绍过两个方法: 一个是插桩日志分析法,一个是借助加固的方法。 插桩日志分析法,理解起来比较... 阅读详情

相关推荐

adb 脚本化Android系统截图和录屏

adb 截图、录屏、

ITPlus的博客 1457

Android 抓取Trace 分析冷启动

使用Trace协助分析应用冷启动 冷启动分析 Trace分析

wqh_0625的博客 3918

当迁移学习遇见室内定位:基于UJIIndoorLoc的跨场景适配实践

本文探讨了迁移学习在跨建筑室内定位中的应用,重点解析了UJIIndoorLoc数据集的特性及其在解决设备差异和环境变化中的关键作用。通过特征工程、迁移学习策略和小样本微调技术,显著提升了定位模型的跨场景适配能力,为实际部署提供了有效解决方案。

weixin_29038155的博客 394

使用adb shell screencap命令截图

adb 截图命令

qq_40126958的博客 4922

NeRF必读:Mip-NeRF总结与公式推导

由于远景近景的分辨率不同,导致经典NeRF对于多尺度场景的表达存在明显瑕疵:NeRF对于近景的重建比较模糊而对于远景的重建出现锯齿。简单粗暴的策略是supersampling,但是费时费力。相较于NeRF使用的位置编码(PE)方式,Mip-NeRF提出了积分位置编码的方式(IPE).这种编码方式可以多尺度地描述空间中的信息分布,make sense.

i_head_no_back的博客 6079

matlab内读取文件目录时斜杠和反斜杠的使用

@matlab内读取文件目录时斜杠和反斜杠的使用TOC matlab内读取文件目录时,斜杠和反斜杠的使用 最近被斜杠和反斜杠弄晕了,于是总结了一下,在此和大家分享一下。 代码 clear; clc; close all; I1= imread('..\zs1.jpg'); %和代码文件夹同目录的图片 (纯反斜杠) I2= imread('../zs2/zs2.j...

weixin_44456694的博客 6574

Android 性能优化【篇四:Trace调试技能汇总】

MTK官方网站介绍了一些关键字来确认IO数据量的请求,详细可以点击我block_rq_insert:表示将一个新的块I/O请求插入到块层请求队列中。当应用程序或者操作系统发起一个读取或写入请求时,这个请求会被插入到块I/O请求队列中等待处理block_rq_issue:表示一个块I/O请求已经提交并开始执行,具体含义是块设备层已经向硬盘或固态驱动器提交了一个请求,并此请求已经在硬盘或驱动器设备上执行。当I/O请求插入到请求队列中表示等待执行,issue。

qq_27672101的博客 1万+

用宝塔面板+CentOS 7.6,30分钟搞定DNF手游私服搭建(附全套资源下载)

本文详细介绍了如何使用宝塔面板和CentOS 7.6在30分钟内快速搭建DNF手游私服。通过图形化界面操作,无需复杂命令,即可完成服务端部署、MySQL数据库配置及客户端适配,适合Linux新手快速上手。

weixin_33737774的博客 601

adb 截屏和录屏命令

screenrecord 是一个 shell 命令支持 Android 4.4(API level 19)以上支持视频格式: mp4一些限制某些设备可能无法直接录制,原因是分辨率太高,如果遇到此类问题,请试着指定较低的分辨率不支持录制过程中屏幕旋转,如果录制过程中旋转,有可能画面被切断录制视频的时候声音不会被录下来### 开始录制命令:说明:录制手机屏幕,视频格式为mp4,存放到手机sd卡里,默认录制时间为180s。

2401_89213302的博客 1712

AI虚拟人物 数字人直播,不用出镜,不用露脸的直播方式(附教程 软件)

我们先来看一组数据,这是我通过蝉妈妈查到的某位虚拟主播的一个带货数据,粉丝还不到 3000 人,每次直播 1 到 4 个小时,30天的总销量达到了1200单,15天,总销售额 2 万,可能相对来说客单价还是比较低,最关键的是才直播了 6 场,如果说他能够一个月直播 20 天,每天花 4个小时去直播,当个副业来做,就可以达到最起码月入 3 万的一个收入水平,我个人觉得是非常的不错的。大家把商品图片放在背景,只要场景设置的不错,场景和产品的关联度高,直播的时候挂上购买链接也会有一定的成交。

. 7万+

将Keil中的变量数组导出

首先,写好导出数据的函数。

小柚子的博客 1952

Android 分析Trace文件步骤

查找与“KeyDispatchingTimeout”和“InputDispatchingTimeout”等关键字相关的线程信息,以定位 ANR 的具体原因。在堆栈信息中,找到应用程序的主线程信息。通过查看时间戳信息,可以确定 ANR 事件发生的时间,进而找出在该时刻发生的事件,从而确定 ANR 的根本原因。总之,通过分析 ANR 日志文件中的关键字、线程信息、堆栈信息和时间戳等信息,我们可以确定 Android 应用程序中 ANR 的具体原因,并在此基础上进行相关的优化和改进。

工宗浩生财指南针 3683

使用 Python 构建 Reddit 热帖爬虫:抓取热门讨论帖和评论

在现代互联网中,Reddit 被誉为全球最大、最活跃的讨论平台之一,汇聚了各种主题的帖子、评论和社交互动。因此,抓取 Reddit 上的热门帖子和评论可以为我们提供一个丰富的文本数据源,可以用于情感分析、话题建模、趋势分析等应用。Reddit 提供了官方的 API,可以让开发者获取包括帖子、评论、用户信息等在内的各种数据。我们可以结合上述方法,抓取多个热门帖子,并将每个帖子的标题、作者、发布时间和评论内容保存到一个数据结构中。每个帖子的对象包含了丰富的信息,如标题、内容、发布时间、作者等。

2201_76125261的博客 382

Android系统 抓trace方法(手机及车机)

andorid抓取trace的三种方法,方便简单。

weixin_41872439的博客 7898

SAP_FI模块_固定资产期初导入全流程(含导入代码)

SAP 期初导入资产主数据以及金额相关的操作全流程记录,包含了批导程序的代码,以及错误记录

风沙的博客 1405

深度学习工具包 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")

Android显示系统SurfaceFlinger详解 超级干货

本文详细讲解了Android显示系统SurfaceFlinger,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

WolfKingzyh的博客 1万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Android系统Trace概览

系统跟踪概览 “系统跟踪”就是记录短时间内的设备活动。系统跟踪会生成跟踪文件,该文件可用于生成系统报告。此报告可帮助您了解如何最有效地提升应用或游戏的性能。 Android 平台提供了多种不同的跟踪信息获取途径: Android Studio CPU 性能剖析器 “系统跟踪”应用 Systrace 命令行工具 Perfetto 命令行工具 在您与应用交互时,Android Studio CPU 性能剖析器可实时检查应用的 CPU 使用率和线程活动。您还可以检查方法跟踪记录、函数跟踪记录和系统跟踪记录中的

垮掉的一代人的专栏 7216

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【android 性能分析之perfetto_trace抓取】

自带的trace信息不一定能明确问题点,可以在怀疑的代码中自己加上trace// 开始打点 Debug . startMethodTracing("tracefilename");//运行怀疑有问题的代码 // 结束打点 Debug . stopMethodTracing();默认的抓取并不能把app中所有方法抓出来,需要在代码中对应位置手动打点才好定位具体问题点,

LLCCQAQ的博客 3205

adb shell截屏录屏命令

一、adb shell screencap截屏指令 通过adb工具里的help指令查看screncap指令的用法: C:\Users>adb shell screencap -help usage: screencap [-hp] [-d display-id] [FILENAME] -h: this message -p: save the file as a png. -d: specify the display id to capture, default 0. I..

qq_39790633的博客 6392

Android技能树点亮计划-Trace的使用

背景 做App启动优化的时候,Trace是优化过程中一个很重要的工具,Trace分析工具包含两种 method trace:抓线程中代码的执行栈和耗时 systrace:抓app使用过程中cpu、线程和锁阻塞等信息 method trace 介绍 通过method trace 抓取线程中执行的方法栈和方法耗时。如图,通过分析主线程的方法调用,解决主线程耗时逻辑。 放大: 按W 键或者向前滑动鼠标的同时按下Ctrl 键 缩小: 按S 键或者向前滑动鼠标的同时按下Ctrl 键 左移: 按A 或者左移.

m0_59162559的博客 4864

Android Trace使用

1. 使用命令比较准确方便,在android源码工程目录下, external/chromium-trace# python systrace.py -help Usage: systrace.py [options] [category1 [category2 ...]] **Example: systrace.py -b 32768 -t 15 gfx input view sched freq** Options: -h, --help show this help ...

startupYH的博客 3871

使用 adb 命令截取 Android 设备的屏幕截图

使用 adb 命令截取 Android 设备的屏幕截图。

galoiszhou的博客 4711

Android抓trace

trace是分析Android性能问题最直接有效的工具,本文介绍了抓取trace的几种方式。

Tank_Mao的博客 2724

Android trace文件分析小技巧

网上有很多trace文件分析博客,但是都是解释anr发生得原因,没有指导anr文件如何着手分析?本篇文章就是讲trace文件怎么切入?

jackzhouyu的专栏 4141

Android Trace

Performance trace

thefzym的专栏 546
上一篇: systrace/perfetto抓取方式分享
下一篇: systrace/perfetto中需要actrace打tag相关方法-车载车机framework系统开发实战
千里马学框架
博客等级 码龄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、付费专栏及课程。

余额充值