车机CarLauncher的Activity多屏模式WindowingMode为WINDOWING_MODE_MULTI_WINDOW疑问解析

Android12 车载开发TaskView实现分屏 这里只给出TaskView的代码,相关联的源码,请看源码,如果想要使用TaskView需要自己去编译frameWork的源码,打包一个aar,或者jar出来使用,否则无法直接使用。1.如果分屏的应用如启动两个应用按照权重占比,互相不叠加在一起,点触摸击事件都可响应,例如左边启动QQ了,右边启动的是微信,二者窗口都可操作。TaskView是谷歌整合安卓多任务多窗口下交互重新重构的独立出来的module,本身继承自ServiceView,TaskView的相关概念性的东西参考。//创建的taskview。 阅读详情
AI摘要

在Android中,当Activity的WindowMode设置为WINDOWING_MODE_MULTI_WINDOW时,可以同一画面显示多个Activity,且它们可能同时处于RESUMED状态。这不同于常规模式下启动新Activity会暂停前一个Activity。文章通过分析`pauseBackTasks`方法和`canBeResumed`判断,揭示了在多窗口模式下,系统如何处理Activity的暂停逻辑,特别是当一个非全屏的Activity覆盖在另一个全屏Activity之上时,不会触发暂停的原因在于WindowingMode的影响。

hi,粉丝朋友们!

   @IntDef(prefix = { "WINDOWING_MODE_" }, value = {
            WINDOWING_MODE_UNDEFINED,
            WINDOWING_MODE_FULLSCREEN,
            WINDOWING_MODE_MULTI_WINDOW,
            WINDOWING_MODE_PINNED,
            WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
            WINDOWING_MODE_SPLIT_SCREEN_SECONDARY,
            WINDOWING_MODE_FREEFORM,
    })

今天来给大家介绍一下再Activity中WindowMode相关的多窗口模式,这个模式相对平时比较少见,但是在分屏模式之自由窗口模式,等存在多个窗口场景就很关键了。这一部分确实不是普通模式的场景,而且每一种模式都是比较难的,今天来分析一下WINDOWING_MODE_MULTI_WINDOW模式的一个疑问。

疑问背景:

activity的WindowMode被设置成了WINDOWING_MODE_MULTI_WINDOW后,或者其他几个非WINDOWING_MODE_FULLSCREEN的WindowMode,为啥可以同一个画面显示多个Activity,而且多个Activity都是Resume的状态。
比如拿我们CarLauncher的地图画面来说:
在这里插入图片描述

具体可以看对应的am stack list看看Task和Activity相关的情况

test@test:~$ adb shell am stack list
RootTask id=1000098 bounds=[303,57][1200,658] displayId=0 userId=10
 configuration={1.0 310mcc260mnc [en_US] ldltr sw1066dp w1196dp h801dp 120dpi xlrg land car finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(303, 57 - 1200, 658) mAppBounds=Rect(303, 57 - 1200, 658) mMaxBounds=Rect(0, 0 - 1200, 800) mDisplayRotation=ROTATION_0 mWindowingMode=multi-window mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_0} as.2 s.29 fontWeightAdjustment=0}
  taskId=1000098: com.android.car.mapsplaceholder/com.android.car.mapsplaceholder.MapsPlaceholderActivity bounds=[303,57][1200,658] userId=10 visible=true topActivity=ComponentInfo{com.android.car.mapsplaceholder/com.android.car.mapsplaceholder.MapsPlaceholderActivity}

RootTask id=1 bounds=[0,0][1200,800] displayId=0 userId=10
 configuration={1.0 310mcc260mnc [en_US] ldltr sw1066dp w1600dp h1042dp 120dpi xlrg land car finger qwerty/v/v -nav/h winConfig={ mBounds=Rect(0, 0 - 1200, 800) mAppBounds=Rect(0, 0 - 1200, 800) mMaxBounds=Rect(0, 0 - 1200, 800) mDisplayRotation=ROTATION_0 mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=home mAlwaysOnTop=undefined mRotation=ROTATION_0} as.2 s.29 fontWeightAdjustment=0}
  taskId=2: com.android.car.settings/com.android.car.settings.FallbackHome bounds=[0,0][1200,800] userId=0 visible=true topActivity=ComponentInfo{com.android.car.carlauncher/com.android.car.carlauncher.CarLauncher}
  taskId=1000095: com.android.car.carlauncher/com.android.car.carlauncher.CarLauncher bounds=[0,0][1200,800] userId=10 visible=true topActivity=ComponentInfo{com.android.car.carlauncher/com.android.car.carlauncher.CarLauncher}


可以看到其实我们桌面是CarLauncher这个Activity,它是覆盖全屏幕,但是发现居然有个MapsPlaceholderActivity的Activity还在它的上面,显示区域Rect(303, 57 - 1200, 658)就是图片绿色部分,属于地图放置部分

通过dumpsys activity activities可以看出MapsPlaceholderActivity ,CarLauncher两个Activity都属于state=RESUMED状态

大家如果正常理解是不是惊呆了?为啥有两个Activity都是Resumed,正常启动新的Activity时候是不是之前Activity就要Paused,那么这个是在框架怎么实现的不会对之前的Activity进行Paused

解答:

需要解答该问题,其实可以从Activity的是怎么被pause地方进行入手
以前讲解过进入pasue主要pauseBackTasks方法进行

   boolean pauseBackTasks(ActivityRecord resuming) {
      //省略

            leafTask.forAllLeafTaskFragments((taskFrag) -> {
                final ActivityRecord resumedActivity = taskFrag.getResumedActivity();
            
                if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) {
                    if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
                        someActivityPaused[0]++;
                    }
                }
            }, true /* traverseTopToBottom */);
        }, true /* traverseTopToBottom */);
        return someActivityPaused[0] > 0;
    }

在这里插入图片描述

具体可以看下面堆栈:

05-16 22:55:01.987   633  1162 I WindowManager: java.lang.Exception
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1205)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5003)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4938)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2260)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1935)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1661)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1216)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:702)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.ActivityStartController.startActivityInPackage(ActivityStartController.java:283)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.wm.ActivityTaskManagerService$LocalService.startActivityInPackage(ActivityTaskManagerService.java:5445)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.am.PendingIntentRecord.sendInner(PendingIntentRecord.java:483)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.am.PendingIntentRecord.sendWithResult(PendingIntentRecord.java:309)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.am.ActivityManagerService.sendIntentSender(ActivityManagerService.java:5384)
05-16 22:55:01.987   633  1162 I WindowManager: 	at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:4402)
05-16 22:55:01.987   633  1162 I WindowManager: 	at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2638)
05-16 22:55:01.987   633  1162 I WindowManager: 	at android.os.Binder.execTransactInternal(Binder.java:1280)
05-16 22:55:01.987   633  1162 I WindowManager: 	at android.os.Binder.execTransact(Binder.java:1244)

如果是正常模式肯定就会进入Pasue,但是WINDOWING_MODE_MULTI_WINDOW不会进入,这个是为啥?那就要具体分析怎么才可以进入这个taskFrag.startPausing的条件:

  if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) {
                    if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
                        someActivityPaused[0]++;
                    }
                }

这个地方有resumedActivity这个一般就是Carauncher,
resuming就是我们的MapsPlaceholderActivity,
taskFrag就是Carauncher的Task

taskFrag.canBeResumed代表就是这个taskFrag是否可以处于Resumed状态
如果为true则不可以pasue之前activity,如果为false就是要pause前面Activity(CarLauncher)

   boolean canBeResumed(@Nullable ActivityRecord starting) {
        // No need to resume activity in TaskFragment that is not visible.
        return isTopActivityFocusable()
                && getVisibility(starting) == TASK_FRAGMENT_VISIBILITY_VISIBLE;
    }

canBeResumed的判断又是对Task的isTopActivityFocusable()和getVisibility(starting)进行判断,这里isTopActivityFocusable一般都为true,getVisibility是关键,也就是再不进行pause
下面重点看getVisibility实现:

int getVisibility(ActivityRecord starting) {
        //省略部分
        if (parent.asTaskFragment() != null) {
           //省略部分
        final List<TaskFragment> adjacentTaskFragments = new ArrayList<>();
        for (int i = parent.getChildCount() - 1; i >= 0; --i) {
            final WindowContainer other = parent.getChildAt(i);//遍历TaskDisplayarea所有子节点,赋值other
            if (other == null) continue;

            final boolean hasRunningActivities = hasRunningActivity(other);
            if (other == this) {//这里条件是要other和this相等才可以
               //省略部分
                // Should be visible if there is no other fragment occluding it, unless it doesn't
                // have any running activities, not starting one and not home stack.
                //这个地方本身有CarLauncher这个hasRunningActivities满足为true,所以shouldBeVisible为true
                shouldBeVisible = hasRunningActivities
                        || (starting != null && starting.isDescendantOf(this))
                        || isActivityTypeHome();
                break;
            }
			//但是CarLauncher的Task在MapsPlaceholderActivity的底部,所以先遍历到MapsPlaceholderActivity的Task
            final int otherWindowingMode = other.getWindowingMode();
            //关键判断MapsPlaceholderActivity的task的WindowingMode是否属于WINDOWING_MODE_FULLSCREEN,如果属于这里就会return INVISIBLE,这里也就是之前会导致pause的关键,但是因为我们设置成了WINDOWING_MODE_MULTI_WINDOW,所以无法进入这个里面
            if (otherWindowingMode == WINDOWING_MODE_FULLSCREEN) {
                if (isTranslucent(other, starting)) {
                    // Can be visible behind a translucent fullscreen TaskFragment.
                    gotTranslucentFullscreen = true;
                    continue;
                }
                return TASK_FRAGMENT_VISIBILITY_INVISIBLE;
            } else if (otherWindowingMode == WINDOWING_MODE_MULTI_WINDOW
                    && other.matchParentBounds()) {
                    //这里虽然判断了WINDOWING_MODE_MULTI_WINDOW,但是因为MapsPlaceholderActivity的bound区域不是全屏,所以也不会进入这里进行INVISIBLE
                if (isTranslucent(other, starting)) {
                    // Can be visible behind a translucent TaskFragment.
                    gotTranslucentFullscreen = true;
                    continue;
                }
                // Multi-window TaskFragment that matches parent bounds would occlude other children
                return TASK_FRAGMENT_VISIBILITY_INVISIBLE;
            }
           //省略

        if (!shouldBeVisible) {
            return TASK_FRAGMENT_VISIBILITY_INVISIBLE;
        }

        // Lastly - check if there is a translucent fullscreen TaskFragment on top.
        return gotTranslucentFullscreen
                ? TASK_FRAGMENT_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT
                : TASK_FRAGMENT_VISIBILITY_VISIBLE;
    }

代码较多较复杂,看一两次很难看懂的总结一下:
Visible变量影响关键
1、遍历当前的所有Task,根据先后顺序,一般先遍历的Task肯定是最先的MapsPlaceholderActivity的Task
2、导致会进行Pause关键是如果MapsPlaceholderActivity的Task是WINDOWING_MODE_FULLSCREEN或WINDOWING_MODE_MULTI_WINDOW但是一定要可以覆盖全部下面的Task,说白了就是如果上面Task会把自己覆盖那么就一定会导致INVISIBLE

3、一旦不会覆盖,那么自己Task有正在执行Activity,那么就会返回VISIBLE

具体图如下:

在这里插入图片描述
在这里插入图片描述

Android 车载应用开发与分析(5) - CarLauncher(一) 在之前的Android车载应用开发与分析(1) - Android Automotive概述与编译中了解了如何下载以及编译面向车载IVI的Android系统,一切顺利的话,运行模拟器,等待启动动画播放完毕后,我们所能看到的第一个APP就是车载android的桌面,而这就是本篇文章的重点 - CarLauncher。 本篇文章以解析Android 11 源码中CarLauncher为主。为了便于阅读源码,现将CarLauncher的源码整理成可以导入Android Studio的结构,源码地址:https:/ 阅读详情

相关推荐

手把手调试:用adb shell am stack list分析车机多屏显示问题(以CarLauncher为例)

本文深入解析车机多屏显示异常问题,以CarLauncher为例,通过adb shell am stack list和dumpsys命令组合,详细分析WindowingMode多屏模式(WINDOWING_MODE_MULTI_WINDOW)的运作机制。提供实战排查步骤和修复方案,帮助开发者解决Activity重叠、窗口消失等典型问题,优化车机多屏显示效果。

weixin_30292745的博客 253

Android车载AOSP Android 12 CarLauncher的替换

替换车载CarLauncher

weixin_43742853的博客 1944

Android车载开发避坑指南:为什么CarLauncher和地图App能同时保持Resumed状态?

本文深入解析Android车载开发中多窗口模式下的特殊现象:CarLauncher和地图应用能同时保持Resumed状态。通过剖析WINDOWING_MODE_MULTI_WINDOW机制、TaskFragment可见性判断及框架层实现原理,提供实用的调试技巧与避坑建议,帮助开发者应对车载环境下的多任务处理挑战。

weixin_30924239的博客 415

Android车机开发避坑:CarLauncher与地图Activity同时Resumed?多窗口模式源码解析

本文深入解析Android车机开发中CarLauncher与地图Activity在多窗口模式(WINDOWING_MODE_MULTI_WINDOW)下同时保持RESUMED状态的源码机制。通过分析AMS核心逻辑和窗口可见性判断规则,揭示车载系统特有的多窗口生命周期管理策略,并提供实用的调试技巧与解决方案,帮助开发者高效应对车机多窗口开发挑战。

weixin_28730353的博客 324

【IVI】12. Android Automotive OS 启动详解-CarLauncher篇

1.AMS启动Home Activity 在SystemServer启动时,在进入PHASE_ACTIVITY_MANAGER_READY阶段,该阶段会告诉ActivityManager可以启动三方代码。并进行相关的初始化。 frameworks/base/services/java/com/android/server/SystemServer.java { …... mActivityManagerService.systemReady(() -> {//ams调用systemReady

从0到1,突破自己 6421

Android USB(type-c)耳机调试分析(十)

简介:优快云博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!】🚀】🚀人生格言:人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.​更多原创,欢迎关注:Android系统攻城狮​1.前言本篇目的:理解Android USB(type-c)耳机调试分析。

Android系统攻城狮 3997

Android12 窗口模式

Android 窗口模式

ocreativityo的博客 2294

URDF模型转换实战:解决SolidWorks到Gazebo的五大常见问题

本文详细解析了从SolidWorks导出URDF模型到Gazebo仿真过程中常见的五大问题及解决方案,包括插件安装、坐标系建立、Link与Joint配置等关键步骤。通过实战经验分享,帮助机器人仿真工程师高效完成模型转换,确保Gazebo仿真准确性。

weixin_29052717的博客 445

Android车载Launcher开发(1) - 显示Widget

Android launcher开发,讲述如何显示其他app的widget到launcher上

NYSM239的博客 8533

从SolidWorks到URDF:插件使用、关节配置与PyBullet仿真避坑指南

本文提供了一份从SolidWorks导出URDF模型并导入PyBullet进行仿真的完整实战指南。详细讲解了SolidWorks插件的正确安装与配置、关节类型的选择与坐标系对齐的核心技巧,并针对PyBullet仿真中常见的模型散架、路径错误、物理属性异常等问题提供了深度避坑解决方案,帮助机器人开发者高效完成从设计到仿真的全流程。

weixin_29081101的博客 543

从零开始玩转机械臂:用Matlab+Robotics Toolbox实现四自由度机械臂运动仿真

本文详细介绍了如何利用Matlab及其Robotics Toolbox工具箱,从零开始构建并仿真一个四自由度机械臂。通过D-H参数建模、正向运动学验证、交互式操控以及轨迹规划等实践步骤,帮助初学者在虚拟环境中直观理解机器人运动学核心概念,为后续硬件实现奠定坚实基础。

weixin_29055699的博客 325

Android 车载应用开发与分析 - CarLauncher

虽然Launcher也是一个APP,但是它涉及到的技术点却比一般的APP要多。CarLauncher作为IVI系统的桌面,需要显示系统中所有用户可用app的入口,显示最近用户使用的APP,同时还需要支持在桌面上动态显示如地图、音乐在内各个APP内部的信息,在桌面显示地图并与之进行简单的交互。Launcher是安卓系统中的主要程序组件之一,安卓系统中如果没有Launcher就无法启动安卓桌面,Launcher出错的时候,安卓系统会出现“进程 com.android.launcher 意外停止”的提示窗口。

工宗浩生财指南针 4477

河洛理数【陈抟】每月月卦推演每日运卦

Step2:每卦中的日爻遇到二十四节气中的当日为节(月初)或气(月中)的时候,所代表的日期需要变更。正常来说,屯卦分别代表初一到初六,但是由于当月初二时立秋节,所以初爻就不能作为初一、而是要作为立秋节开始时(文中还精算到了立秋是从初二的午时开始),如下。说的代表月运的基础卦上进行当月日卦的推演方式。老样子,我们还是按照书中举得例子卦在这边进行一步步的推演,最后做总结。Step1:从月卦爻下一爻开始,自下而上,进行五个爻的爻变,新推演的每个卦代表六天,如下。假设当月月卦是即济卦,月爻在二爻,如图所示(

Daniel专栏 764

Android 设置全屏显示的方法

方法一:在 setContentView 之前设置如下代码 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 方法二:在Androi...

WuDong 7828

【推荐100个unity插件】动画重定向,快速在不同角色间共享动画,共用非人形Humanoid(泛型generic)动画——Retarget Pro

Retarget Pro是一款高效的Unity动画重定向工具,可快速在不同角色间共享动画。主要特点包括:1分钟快速设置,支持编辑器和运行时重定向;适用于人形、动物、武器等各类角色;提供基础重定向、IK重定向和FPS专用重定向三种功能模块;通过Rig组件和骨架资产实现骨骼链匹配,支持批量处理。插件包含示例项目和预设资源,操作简便且效果优于Unity原生Humanoid系统,特别适合处理手指等精细动画。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 547

python全栈入门到实战【基础篇 01】Python初识:定位、优势与发展历程

本文介绍了热门编程语言Python。它是解释型高级语言,具通用、入门友好、胶水型特点,以简洁易读为设计哲学。优势包括语法简洁高效、生态庞大、跨平台、社区活跃、应用广泛、门槛低。发展历经诞生(1989-1994,吉多创建,1994年1.0发布)、成长(版本迭代,3.0发布)、崛起(Web与大数据推动)、爆发(AI浪潮助推)及持续迭代阶段。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 1万+

多窗口模式(multi-window mode)

多窗口模式(multi-window mode):是android7.0(API24)添加的,可以有分屏模式(split-screen mode),画中画模式( Picture-in-Picture mode),自由模式( freeform mode用户自动调整activity的大小) 1.进入多窗口模式的方法有两种: 在最近打开窗口( Overview screen)中,长按activ

蔷薇_wendy的博客 1万+

【肝帝一周总结:全网最全最细】十万字python教程,学不会找我!教到你会为止!!内容超多,建议收藏慢慢看!

文章目录前言一定要看python入门python缩进Python注释Python 变量1. 定义理解2. 变量名命名3. 分配多个值4. 输出变量5. 全局变量 前言一定要看 python能干什么?有什么用?好处在哪?不要我讲了,这不是我在博客该讲的,言简意赅就是:通俗易懂,上手快,实用强。我会根据自己个人理解以及国外官网翻译为中文对大家进行讲解。完整源码我也会在最下面带上地址。内容过多,我不会全部演示,你完全可以复制粘贴到自己的pycharm上运行即可。 不管是国内的菜鸟教程还是我在这里的翻译,至少你跟

全栈川川 5万+

Android am与pm命令详解

前言:am全称为Activity Manager,活动管理器,可以用来控制activity、service; pm全称Package Manager 包管理器,用以管理系统中安装的应用。 adb shell进入android的命令界面后可执行am与pm命令 am命令大全 启动Activity start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>] [--sampling INTER.

pigdreams的博客 7084

【LaTex】3.4 立体几何

本文介绍了使用LaTeX的tikz包绘制立体几何图形的两种方法。首先展示了基础立方体的绘制代码,通过定义8个顶点坐标并连接各边完成绘制。接着讲解了scope功能在3D绘图中的应用,包括标准平面(xy、xz、yz)的绘制方法,以及任意平面的定义技巧。重点说明了如何通过定义平面原点、x和y方向单位向量来创建旋转后的绘图平面,并以45°旋转的yz平面为例演示了圆的绘制。文章提供了完整的代码示例和对应的效果图示,展示了tikz在3D绘图中的灵活性和强大功能。

你的指尖有改变世界的力量 2456

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

车载开发核心技术-CarLuncher启动流程

CarLuncher作为车载开发的一个重要组成部分,是指车载系统中的启动器应用程序。它是用户进入车载娱乐系统和其他车载应用的入口。CarLuncher负责管理应用程序的安装、卸载、启动和显示,同时提供用户界面和操作方式,使用户能够轻松地访问和使用各种车载应用。CarLuncher是车载系统中的一个应用程序,也称为启动器(Launcher)。它是用户进入车载娱乐系统和其他车载应用的入口。CarLuncher的主要作用是管理和提供车载应用程序的启动和显示功能。

鸿蒙的技术博客 1249

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

这是一份全面&详细的Android 车载系统开发入门指南

目前的就业形势越来越严峻,很多大中小厂因为业务停滞不前都选择“精简人员”,节约成本。对于Android开发来说,市场的冷静,明显可以感知到企业招聘门槛的提高。就未来发展来说,选择一个正处于时代风口的细分领域深耕最佳。车载开发无疑是具有这个潜力的领域,人工智能,物联网的发展,车企“缺芯少魂”刺激了车载开发走上风口。想要抓住转行车载行业的好机会,大家应该紧锣密鼓的开始准备起来了。为了帮助大家更好的掌握...

Android技术之家 3561

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

AndroidQ 分屏窗口模式 (AMS部分)

1. 多窗口 1.1 栈 Android7.0开始支持多窗口,多窗口分为三种,画中画,分屏,自有窗口,多窗口的核心原理其实就是分栈和设置栈边界, 分栈即把不同窗口模式下的Activity放在不同的ActivityStack中,Android7.0为区分不同ActivityStack定义了不同stackId: /** First static stack ID. */ public static final int FIRST_STATIC_STACK_ID = 0;

qq_34211365的博客 1万+

android framework车载桌面CarLauncher的TaskView详细源码分析

可以明显看出这里systemserver跨进程回调到了ShellTaskOrganizer的onTaskAppeared,在这个方法进行精准匹配到TaskView关心的Task变化,然后进行通知。上面第一步已经实现了CarLauncher可以监听Task的相关行为,注意这里肯定是所有的Task行为,但是TaskView它自身只关心Map相关的Task,那么这里是怎么精准通知的呢?通过这个cookie即可以精准的把系统回调的TaskInfo匹配到对应的TaskView。启动Activity相关堆栈。

liaosongmao1的专栏 1769
上一篇: android 13 Zygote fork新的app进程源码分析-车载车机手机framework实战开发
下一篇: android13 FLAG_BLUR_BEHIND 壁纸高斯模糊,毛玻璃背景方案设计-千里马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、付费专栏及课程。

余额充值