重重学app冷启动流程桌面点击到SplashWindow显示与移除流程剖析-aosp16

adb shell wm 命令实战:3个核心参数(size/density/overscan)修改与恢复 本文深入解析了ADB Shell WM命令在屏幕参数调优与自动化测试中的应用,重点介绍了size、density和overscan三个核心参数的修改与恢复方法。通过实战案例和脚本示例,帮助开发者高效模拟多种显示环境,提升移动应用适配测试效率。 阅读详情

背景

在统计了学员们系统fw面试题后,发现桌面点击到app展示第一帧的源码流程这类题目是被考的最多的,基本上属于ams,wms必问的面试题。但是问这类题目绝不是死记硬背可以搞定的哈,面试官们都会对流程中的一些点进行灵活考察等,当然你只要掌握整个流程,无论别人怎么问其实都可以应答如流。

本文我们来基于aosp16 r4的源码给大家复习一下原来ams,wms课程中给大家讲解的SplashWindow的显示与删除流程。

1. 冷启动SplashStartingWindow流程概览

冷启动(Cold Start)是指目标应用进程尚不存在,需要 Zygote 重新 fork 的场景。

SplashStartingWindow核心设计精髓:SplashStartingWindow 的创建完全与目标应用进程的生命周期解耦。它在 Zygote fork 之前就已经由 Shell(SystemUI)进程创建并显示到屏幕上——所以用户点击图标后能"秒开"看到视觉反馈,从而提升app冷启动的用户体验。

下面是详细的整体的流程时序图情况,主要涉及了5个进程部分:
在这里插入图片描述


2. 第一阶段:Launcher 点击 → AMS

2.1 点击事件处理

文件:packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.java

用户点击桌面图标时,ItemClickHandler.onClick() 被触发。从 View 的 tag 中取出 ItemInfo,根据类型分发:

public static void onClick(View v) {
    if (itemInfo instanceof WorkspaceItemInfo || itemInfo instanceof AppInfo) {
        onClickAppShortcut(v, (WorkspaceItemInfo) itemInfo, source);
    }
}

最终通过 startAppShortcutOrInfoActivity() 构造 Intent,调用 Launcher.startActivitySafely():

文件:packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

// ~line 2106
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    super.startActivity(view, intent, optsBundle);
}

第一次 IPC:Launcher 进程 → AMS(IActivityManager.startActivity())。


3. 第二阶段:AMS 处理 —— 在进程 fork 前创建 Splash

3.1 ActivityStarter → startSpecificActivity

文件:services/core/java/com/android/server/wm/ActivityStarter.java

// execute() → executeRequest() → startActivityInner()
mRootWindowContainer.resumeFocusedTasksTopActivities();

文件:services/core/java/com/android/server/wm/ActivityTaskSupervisor.java

// ~line 1181
void startSpecificActivity(ActivityRecord r, ...) {
    final WindowProcessController wpc =
            mService.getProcessController(r.processName, r.info.applicationInfo.uid);
    if (wpc != null && wpc.hasThread()) {
        // 冷启动时 wpc == null,跳过此分支
        realStartActivityLocked(r, wpc, ...);
    } else {
        // ★ 注意调用顺序:
        r.showStartingWindow(true /* taskSwitch */);  // 先创建 Starting Window
        mService.startProcessAsync(r.processName, ...); // 再 fork 进程
    }
}

关键:showStartingWindow() 在 startProcessAsync() 之前调用。在 Zygote fork 新进程之前,Splash Window 已经开始创建。

3.2 getStartingWindowType() 决策

文件:services/core/java/com/android/server/wm/ActivityRecord.java ~line 2411

private int getStartingWindowType(boolean newTask, boolean taskSwitch,
        boolean processRunning, boolean allowTaskSnapshot,
        boolean activityCreated, boolean activityAllDrawn, TaskSnapshot snapshot) {

    // 冷启动时:newTask=true 或 processRunning=false → 直接进入此分支
    if ((newTask || !processRunning || (taskSwitch && !activityCreated)) && !isActivityHome) {
        return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
    }

    if (taskSwitch) {
        if (allowTaskSnapshot && isSnapshotCompatible(snapshot)) {
            return STARTING_WINDOW_TYPE_SNAPSHOT;
        }
        if (!isActivityHome) {
            return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
        }
    }
    return STARTING_WINDOW_TYPE_NONE;
}

冷启动中 processRunning=false,直接返回 STARTING_WINDOW_TYPE_SPLASH_SCREEN。

3.3 addStartingWindow → SplashScreenStartingData

文件:services/core/java/com/android/server/wm/ActivityRecord.java ~line 2285

boolean addStartingWindow(String pkg, int resolvedTheme, ...) {
    // 守门员:如果已有绘制完成的窗口,不需要 starting window
    final WindowState mainWin = findMainWindow(false);
    if (mainWin != null && mainWin.isDrawn()) {
        return false;
    }

    // 获取 Task 截图(冷启动时通常为 null)
    final TaskSnapshot snapshot = mWmService.mTaskSnapshotController.getSnapshot(...);

    // 决定类型
    final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
            allowTaskSnapshot, activityCreated, activityAllDrawn, snapshot);

    // ★ 冷启动 → SPLASH_SCREEN
    if (type == STARTING_WINDOW_TYPE_SPLASH_SCREEN) {
        mStartingData = new SplashScreenStartingData(mWmService, resolvedTheme, typeParameter);
        scheduleAddStartingWindow();  // ★ 触发创建
    }
}

3.4 IPC 到 Shell 进程

文件:services/core/java/com/android/server/wm/StartingSurfaceController.java

StartingSurface createSplashScreenStartingSurface(ActivityRecord activity, int theme) {
    return mTaskOrganizerController.addStartingWindow(activity.getTask(), activity, theme);
}

文件:services/core/java/com/android/server/wm/TaskOrganizerController.java ~line 652

StartingSurface addStartingWindow(Task task, ActivityRecord activity, int theme, ...) {
    final StartingWindowInfo info = new StartingWindowInfo();
    info.taskInfo = task.getTaskInfo();
    info.targetActivityInfo = activity.info;
    info.splashScreenThemeResId = theme;

    // ★ IPC 到 Shell
    mTaskOrganizer.addStartingWindow(taskInfo, info);
}

4. 第三阶段:Shell 进程双线程并行渲染 Splash

这是 Android 系统精心设计的性能优化点。

4.1 核心思路

文件:libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java

将图标渲染(CPU/GPU 密集操作)和窗口添加(Binder IPC 阻塞操作)放到两个线程并行执行。

// ~line 123
void addSplashScreenStartingWindow(StartingWindowInfo windowInfo, int suggestType) {
    // 线程同步的"供应商"对象(内部使用 wait/notify)
    final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier();
    final FrameLayout rootLayout = new FrameLayout(context);

    // 主线程回调:在 Choreographer 回调中等待 Worker 的结果并设置内容
    final Runnable setViewSynchronized = () -> {
        SplashScreenView contentView = viewSupplier.get();  // 阻塞等待 Worker
        rootLayout.addView(contentView);
    };

    // ===== 启动两条并行路径 =====

    // 路径A(Worker 线程):预渲染图标 Bitmap
    mSplashscreenContentDrawer.createContentView(context, suggestType, windowInfo,
            viewSupplier::setView,
            viewSupplier::setUiThreadInitTask);

    // 路径B(主线程):添加窗口到 WindowManager
    if (addWindow(taskId, windowInfo.appToken, rootLayout, display, params, suggestType)) {
        mChoreographer.postCallback(CALLBACK_INSETS_ANIMATION, setViewSynchronized, null);
    }
}

4.2 线程同步:SplashScreenViewSupplier

内部使用 synchronized + wait()/notify() 实现阻塞等待:

// ~line 387
private static class SplashScreenViewSupplier implements Supplier<SplashScreenView> {
    private SplashScreenView mView;
    private boolean mIsViewSet;

    // Worker 线程调用
    void setView(SplashScreenView view) {
        synchronized (this) {
            mView = view;
            mIsViewSet = true;
            notify();  // 唤醒主线程
        }
    }

    // 主线程调用 —— 阻塞直到 Worker 完成
    public SplashScreenView get() {
        synchronized (this) {
            while (!mIsViewSet) {
                wait();  // 等待 Worker
            }
            return mView;
        }
    }
}

4.3 添加窗口

protected boolean addWindow(int taskId, IBinder appToken, View view, Display display,
        WindowManager.LayoutParams params, int suggestType) {
    // ★ 与普通 Activity 窗口完全相同的添加路径
    mWindowManagerGlobal.addView(view, params, display, null, context.getUserId());
}

窗口类型为 TYPE_APPLICATION_STARTING,此时 Splash 首帧已显示在屏幕上,而应用进程可能还没开始 fork。


5. 第四阶段:Zygote fork 与应用进程初始化

5.1 Fork 新进程

startProcessAsync() 触发 Zygote socket 通信:

AMS.startProcessAsync() → ProcessList.startProcess() → ZygoteProcess.start()

第三次 IPC:SystemServer → Zygote(socket 通信)。

新进程入口为 ActivityThread.main():

文件:core/java/android/app/ActivityThread.java ~line 9238

public static void main(String[] args) {
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    thread.attach(false);  // 通知 AMS 进程就绪
    Looper.loop();
}

5.2 attachApplication → bindApplication → realStartActivity

private void attach(boolean system) {
    final IActivityManager mgr = ActivityManager.getService();
    mgr.attachApplication(mAppThread);  // ★ IPC 到 AMS
}

第四次 IPC:新进程 → SystemServer。

文件:services/core/java/com/android/server/am/ActivityManagerService.java ~line 4583

private boolean attachApplicationLocked(IApplicationThread thread, ...) {
    thread.bindApplication(...);       // IPC 发送应用初始化数据
    mAtmInternal.attachApplication(app);
}

RootWindowContainer.attachApplication() 遍历属于该进程的顶层 Activity,调用 realStartActivityLocked():

文件:services/core/java/com/android/server/wm/ActivityTaskSupervisor.java ~line 822

boolean realStartActivityLocked(ActivityRecord r, ...) {
    clientTransaction.addCallback(LaunchActivityItem.obtain(...));
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}

6. 第五阶段:Activity 启动与窗口首帧绘制

6.1 客户端处理 LaunchActivity

文件:core/java/android/app/ActivityThread.java ~line 4335

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    activity.attach(appContext, this, ...);  // 创建 PhoneWindow
    mInstrumentation.callActivityOnCreate(activity, r.state);
    return activity;
}

然后是 handleResumeActivity()(~line 5905):

public void handleResumeActivity(ActivityClientRecord r, ...) {
    performResumeActivity(r, ...);  // onResume()

    if (r.window == null && !a.mFinished && willBeVisible) {
        View decor = r.window.getDecorView();
        decor.setVisibility(View.INVISIBLE);
        wm.addView(decor, l);  // ★ 创建 ViewRootImpl,触发渲染
    }
}

wm.addView() 内部创建 ViewRootImpl,驱动 performTraversals() 进行 measure/layout/draw。

6.2 首帧绘制完成 → reportDrawFinished

文件:core/java/android/view/ViewRootImpl.java ~line 5454

private void reportDrawFinished(@Nullable Transaction t, int seqId) {
    mWindowSession.finishDrawing(mWindow, t, seqId);  // ★ IPC 到 WMS
}

第六次 IPC:应用进程 → WMS。


7. 第六阶段:onFirstWindowDrawn → Splash 移除

7.1 WMS 侧:WindowState.finishDrawing()

文件:services/core/java/com/android/server/wm/WindowState.java ~line 5818

boolean finishDrawing(SurfaceControl.Transaction postDrawTransaction, int syncSeqId) {
    // Starting window 绘制完成 → 记录指标
    if (mAttrs.type == TYPE_APPLICATION_STARTING) {
        mWmService.mAtmService.mTaskSupervisor.getActivityMetricsLogger()
                .notifyStartingWindowDrawn(mActivityRecord);
    }
    // ...
}

绘制状态机转换:DRAW_PENDING → COMMIT_DRAW_PENDING → READY_TO_SHOW

7.2 performShowLocked() —— 两种窗口的分岔

文件:services/core/java/com/android/server/wm/WindowState.java ~line 4434

boolean performShowLocked() {
    final int drawState = mWinAnimator.mDrawState;
    if ((drawState == HAS_DRAWN || drawState == READY_TO_SHOW) && mActivityRecord != null) {
        // ★ 关键:根据窗口类型分发
        if (mAttrs.type != TYPE_APPLICATION_STARTING) {
            mActivityRecord.onFirstWindowDrawn(this);   // 应用窗口 → 移除 Splash
        } else {
            mActivityRecord.onStartingWindowDrawn();    // Splash 窗口 → 记录已展示
        }
    }
    mWinAnimator.mDrawState = HAS_DRAWN;
}

设计要点:同一个方法处理两种窗口——应用窗口绘制完成时触发 onFirstWindowDrawn() 移除 Splash;Splash 窗口自身绘制完成时触发 onStartingWindowDrawn() 记录指标。

7.3 onFirstWindowDrawn → removeStartingWindow

文件:services/core/java/com/android/server/wm/ActivityRecord.java

// ~line 6508
void onFirstWindowDrawn(WindowState win) {
    firstWindowDrawn = true;
    if (mStartingWindow != null) {
        win.cancelAnimation();
    }
    removeStartingWindow();  // ★ 移除 Splash
}

// ~line 2729
void removeStartingWindow() {
    if (transferSplashScreenIfNeeded()) {  // 如果 App 设置了自定义退出动画
        return;
    }
    removeStartingWindowAnimation(true);   // 否则走默认动画移除
}

// ~line 2766
void removeStartingWindowAnimation(boolean prepareAnimation) {
    if (mStartingData != null) {
        mStartingData.removeStartingWindow(...);  // IPC 到 Shell 移除窗口
    }
}

通过 IPC 通知 Shell 移除 Splash Window。Shell 侧播放退出动画(默认 400~500ms 的渐隐+位移动画),随后移除窗口。Splash Window 消失,应用首帧接管屏幕。


总结

冷启动 SplashStartingWindow 的完整生命周期:

Splash 创建:startSpecificActivity() → showStartingWindow() → getStartingWindowType() 返回 SPLASH_SCREEN
              → SplashScreenStartingData → scheduleAddStartingWindow() → IPC → Shell 双线程并行渲染
              → Splash 首帧显示 ✓

Splash 移除:App 首帧绘制 → reportDrawFinished() IPC → WindowState.performShowLocked()
              → onFirstWindowDrawn() → removeStartingWindow() → IPC → Shell 播放退出动画 + 移除
              → App 窗口接管 ✓

核心设计精髓:Splash Window 的创建完全与应用进程的生命周期解耦。冷启动中 processRunning=false,系统直接创建 SplashScreenStartingData,通过 Shell 的双线程并行渲染在 ~1 帧内将 Splash 显示到屏幕。应用进程则需要走完 fork → main → attachApplication → bindApplication → LaunchActivity → onCreate → onResume → addView → 首帧 draw 的完整路径。Splash 就是用来填补这段时间的视觉空白。

原文地址:

https://mp.weixin.qq.com/s/DH0zQZEk2qD46946LdqNNw

SplashScreen的添加与移除分析 写过 APP 同学都知道稍微有规模的应用启动的第一个都是 一个 SplashActivity ,也就是常说的“闪屏页”,而不是会是有复杂业务的 “MainActivity”。这个 SplashActivity 的内容一般也很简单,要么是一个图片,或者是一个 logo,有的就是简短的一些文案。比如微信启动的时候会先显示一个“月球”的图片。为什么要先显示这个 SplashActivity? 阅读详情

相关推荐

Android WMS实战:从一次“窗口漂移”Bug调试,聊聊WindowManagerService的布局与事件分发

本文通过一个Android电商App中悬浮购物车图标出现'窗口漂移'Bug的实战案例,深入分析了WindowManagerService(WMS)的布局与事件分发机制。文章详细探讨了WMS在Android 10中的新特性如何影响窗口定位,以及触摸事件分发异常的原因,并提供了针对性的修复方案和最佳实践建议。

weixin_28705087的博客 362

Qt:35---Splash窗口与登录窗口

一、Splash窗口 什么是Splash窗口?一般在大型应用程序启动时会显示一个启动画面,这个启动画面即Splash窗口 特点:Splash窗口一般被设计为一个无边对话框,在Windows任务栏不显示当前窗口的图标信息。 我们通常在Splash窗口中只显示一个图片,并展示软件的信息等 使用场景:Splash窗口显示的时候,程序一般在后台做一些比较耗时的启动准备工作,等到软件的准备工作完成之...

董哥的黑板报 2257

Android分屏功能实现源码解析与实战

Android分屏模式允许用户在同一屏幕上并行运行两个应用或同一应用的多个实例,通过系统级窗口管理服务(WindowManagerService)与ActivityManagerService协同调度,实现多窗口布局的分配与生命周期管控。自Android N(API 24)引入官方支持以来,系统通过机制动态处理窗口堆叠、焦点控制与尺寸协商。// 系统判断是否支持多窗口的关键调用。

weixin_30978239的博客 1050

WPF程序启动加载splash screen等待的方法

最近做项目,点开WPF程序,界面半天不打开,要过一会界面才出来,于是想到给它做一个splash window. 最开始想到的方法是:程序启动的时候,new 一个窗口(带有动画的等待),调用Show方法不阻塞后面的进行来显示。如下所示:namespace WPF_SplashTest { /// <summary> /// Interaction logic for App.xaml

lishuangquan1987的博客 1万+

从解压到编译:手把手带你用TeXstudio搞定第一篇ACM LaTeX论文

本文详细指导如何使用TeXstudio从解压ACM LaTeX模板到成功编译第一篇学术论文的全过程。涵盖环境准备、模板配置、TeXstudio设置及常见问题排查,特别针对ACM会议论文格式要求,帮助学术新人快速掌握LaTeX写作技巧。

weixin_30655569的博客 255

DAC8568控制器实战:如何用STM32实现多通道同步输出(附完整代码)

本文详细介绍了如何使用STM32微控制器驱动TI的DAC8568多通道DAC控制器,实现高精度的多通道同步模拟信号输出。内容涵盖硬件设计要点、SPI时序精准配置、驱动层命令构建,并重点解析了通过LDAC引脚实现同步更新的核心策略,提供了完整的代码框架和实战案例,帮助工程师快速解决多通道同步输出的工程难题。

weixin_29179311的博客 173

给软件增加一个启动屏幕来提升启动体验

1. 写在开始 常见的大型软件,如Word、Excel、Photoshop等等,由于启动时要加载很多模块,为了提高界面响应,都会在在启动时会先打开一个小窗口,等到主界面初始化完成之后再关闭。这样做的好处是用户双击打开程序后,便可以得到反馈”程序打开了,正在启动中,请耐心等待“。同时还可以实时获取软件启动进度,这对于提升用户体验是有很大的帮助。 试想,如果用户双击了一个文件,等待5秒钟后还没打开,是...

老老实实地搬砖 917

新手必看:瑞萨MCU选型时,QFP、QFN、BGA这些封装到底该怎么选?(附选型避坑指南)

本文详细解析了瑞萨MCU选型中QFP、QFN、BGA等封装的特点与适用场景,提供实战避坑指南。通过对比封装的空间占用、散热能力、焊接难度等核心维度,帮助工程师根据具体需求选择最合适的芯片封装,避免因选型不当导致的高成本与生产问题。

weixin_26965807的博客 421

WMS窗口的数据分析

使用winscope手机要处于root状态才能使用使用手机自带的winscope在手机设置里面,找到开发者选项->快捷设置开发者图块->打开 “ Winscope跟踪 ”打开后复现问题,最后再关闭这个开关,就表示抓取完成导出文件adb pull /data/misc/wmtrace把导出文件在源码路径的android-13.0.0_r6/prebuilts/misc/common/winscope/winscope.html打开即可。

cxtywhxd的专栏 426

VS Code配置MASM32汇编环境:从安装到调试的完整指南

本文提供了一份详尽的指南,教你如何在VS Code中配置MASM32汇编开发环境,实现从安装、环境变量设置到编写、编译和调试32位Windows汇编窗口程序的完整工作流。通过集成现代编辑器的便利性与经典汇编工具链,旨在降低学习门槛,提升底层开发效率。

nn3456的博客 487

地震数据可视化必备:5分钟读懂SEGY道头字段全解析(含坐标定位指南)

本文深入解析了SEGY文件格式中道头坐标字段的提取与可视化方法。针对地震数据处理中的常见痛点,详细介绍了sx/sy、gx/gy等关键坐标字段的二进制解析、比例因子应用、单位转换及常见问题解决方案,并提供了实用的Python代码示例,帮助开发者实现从SEGY文件到三维空间可视化的完整流程。

echo99的专栏 1013

当你只有一个设备的时候,如何做好屏幕适配

版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有。 每周会统一更新到这里,如果喜欢,可关注公众号获取最新文章。 未经允许,不得转载。 一、多机型 UI 适配 在 Android 开发的工作日常中,UI 适配是一件比较重要的事情。一般开发新的功能,有新的页面,最终开发完成发布之前,都需要让设计师来审 UI 效果。 而有时候,明明我们已经在一款标准的 3 倍手...

weixin_33937499的博客 384

解决此平台不支持虚拟化的 Intel VT-x/EPT故障问题

当我们在VMware Workstation虚拟机上【启用】虚拟系统(如:Windows10)所在的虚【拟机设置】【处理器】【虚拟化引擎】下面的【虚拟化 Intel VT-x/EPT 或AMD-V/RVI(V)】内容后,在启动虚拟系统时,虚拟系统无法启动,且弹出【此平台不支持虚拟化的 Intel VT-x/EPT。不使用虚拟化的 Intel VT-x/EPT,是否继续】窗口

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 1万+

【用法总结】抓取main_log、events_log、kernel_log日志的方法

Android系统提供了多种日志缓冲区用于开发调试,包括main(应用/系统日志)、system(系统组件)、events(事件日志)、radio(通信相关)等。通过logcat命令可分别查看不同日志:logcat -b main查看应用日志,logcat -b events分析页面生命周期和进程状态,adb shell cat /proc/kmsg获取内核日志。这些日志分别用于定位应用问题、分析ANR/进程异常以及排查底层系统问题,是Android开发调试的重要工具。

TechMix的博客 509

linux arm64 Debian12移植操作手册

2023年6月10号Debian官方出了debian12 arm64版本的。如果需要完全适配这个系统的话,需要linux6.10版本。应客户的需求,需要在Debian11升级为Debian12版本。

qq_45147279的博客 2169

Python爬虫实战:利用Playwright与反反爬技术抓取Crunchbase企业数据

在当今数据驱动的商业环境中,获取准确的企业信息对于市场分析、竞争情报和投资决策至关重要。Crunchbase作为全球领先的企业信息平台,包含了数百万家公司、投资者和关键人员的详细数据。本文将深入探讨如何使用Python最新爬虫技术Playwright,结合多种反反爬策略,高效抓取Crunchbase企业数据。我们将从爬虫基础概念讲起,逐步深入到高级技巧,并提供完整的代码实现,帮助读者掌握现代网络数据采集的核心技术。网络爬虫技术自互联网诞生以来经历了显著演变。

2201_76125261的博客 1833

安卓焦点窗口切换

焦点窗口切换涉及模块较多,需要经过WMS->SF->Input三个模块传递其中对sf传给input这段相关的通信存疑,网上资料也比较少且安卓U上也有函数改动,希望能有大佬补充,上面相关流程有些地方可能不对,涉及到多个进程。

Penguin 5762

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Event log的各 TAG流程分析

Event log中有很多TAG通过他们可以分析一些运行是耗时在哪个区间。 在终端打印adb shell -b events ,Event log常见的启动应用打印log: R版本正常一个应用冷启动的创建流程: wm_task_created--》wm_stack_created--》wm_create_task--》wm_create_activity--》 am_proc_start--》am_proc_bound--》wm_restart_activity--》 wm_set_resumed_act.

一杯咖啡的专栏 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

StartingWindowController

StartingWindowController

我的博客 504

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Windows Subsystem for Android完整指南:如何在Windows 11上免费运行Android应用

你是否曾经想过在Windows电脑上直接运行手机应用?是否厌倦了在不同设备间切换的麻烦?Windows Subsystem for Android(简称WSA)为你打开了Windows 11与Android生态融合的大门!这个神奇的"安卓子系统"让Windows 11瞬间变身为跨平台应用中心,无论是刷抖音、玩手游还是办公学习,都能在电脑上轻松实现。本文将为你揭秘WSA的完整安装配置流程,让你从零开

gitblog_00921的博客 168

Android ADB Shell 常用命令

本文总结了Android设备在Linux系统下的连接排错方法和常用ADB命令指南。主要内容包括:1) 解决Linux无法识别Android设备的udev规则配置方法;2) 应用包管理命令(pm)的使用技巧,包括查看、清除应用数据等;3) Activity管理(am)命令详解,涵盖启动组件、发送广播等操作;4) 文件系统操作与搜索命令;5) 日志记录与调试技巧;6) 屏幕截图和录制方法;7) 高级系统操作如解锁Bootloader等。这些命令涵盖了Android开发调试中的常见需求,从基础连接到高级系统操作,

u010345983的博客 1万+

11. WindowManagerService工作原理 - View显示的幕后英雄

fill:#333;important;important;fill:none;窗口管理添加/移除窗口窗口层级排序窗口状态维护Surface管理Surface创建与分配SurfaceControl操作Transaction提交布局计算Frame计算Insets处理约束应用动画系统动画触发变换应用性能优化输入分发InputChannel注册焦点管理事件路由与SF协作Transaction机制同步策略渲染协调窗口生命周期管理。

时代我西的博客 778

wms开发常用调试开发技巧之WMShell的实用命令

这里有几个WMShell下面还有若干个子命令compatui,protolog,splitscreen等,可以使用这些子命令进行更加精确的控制WMShell相关的一些给你,当然如果没有输入任何子命令情况下,那就是默认输入所有WMShell的内部dump输出。在wms窗口开发工程师日常工作中,经常需要和WMShell打交道,比如分屏,自由窗口,startingwindow等都移入到了WMShell中。我们比较熟悉的SplitScreen相关,Pip相关,单手模式等都有相关的dump信息输出。

learnframework的博客 893

Android U WMShell动画调用堆栈

简单介绍WMshell动画调用的堆栈

yimelancholy的博客 2226

Android 12 上全新的应用启动画面,适配一下?| 开发者说·DTalk

本文原作者:小虾米君,原文发布于: TechMerger。早期的 Android 上 App 的启动速度常为人诟病,如今的启动表现已不逊 iOS。Google 针对系统的不断优化绝对功不...

Android开发者 1770

Ursa.Avalonia启动窗口:SplashWindow的加载动画

在现代桌面应用程序开发中,启动窗口(SplashWindow)不仅仅是展示Logo的简单界面,更是用户体验的重要组成部分。一个精心设计的启动动画能够: - **提升应用感知价值**:专业的外观给用户留下良好第一印象 - **掩盖加载延迟**:在后台初始化时提供视觉反馈 - **建立品牌识别**:通过动画效果强化品牌形象 - **增强用户耐心**:让等待时间变得不那么漫长 Ursa.Avalon...

gitblog_00266的博客 798
上一篇: 安卓fw系统必知必会进程线程与性能监控命令详解
下一篇: AI替代一切工作?AI辅助学习Framework开发经验技巧分享
千里马学框架
博客等级 码龄6年 1万+粉丝 651原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

千里马学框架

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

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

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

打赏作者

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

抵扣说明:

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

余额充值