56-Android之SystemUI默认通知展开

本文介绍如何在SPRD Android 10 SC9832E平台上实现通知默认展开的功能。通过修改frameworks/base/packages/SystemUI/res/values/config.xml文件中的配置项config_alwaysExpandNonGroupedNotifications来达到目的。

56-Android之SystemUI默认通知展开


平台:SPRD Android10 SC9832E

功能实现要求,需要通知需要默认展开。

frameworks/base/packages/SystemUI/res/values/config.xml

<bool name="config_alwaysExpandNonGroupedNotifications">true</bool>  <!--TODO,修改,默认为false-->
<think>我们首先需要理解用户的问题:用户观察到在Android日志中,即使没有显式设置启动模式(launch mode),Activity也只启动了一个实例。用户想知道原因,并希望配置以启动两个实例。 分析: 1. 在Android中,Activity的启动行为由启动模式(launch mode)和任务栈(task)管理机制决定。 2. 如果没有显式设置启动模式,则使用默认的启动模式:standard。 3. standard模式下,每次启动Activity都会创建新的实例,除非有特殊情况(例如使用了FLAG_ACTIVITY_NEW_TASK等标志)。 为什么只启动了一个实例? 可能的原因: - 用户可能是在同一个任务栈(task)中连续启动同一个Activity,但日志显示只有一个实例,这不符合standard模式的行为。 - 另一种可能是,用户可能通过某种方式(例如按了返回键)结束了前一个实例,然后再启动,但用户没有意识到。 - 还有一种可能是,用户使用了Intent标志(如FLAG_ACTIVITY_CLEAR_TOP)或非standard的启动模式(如singleTop、singleTask、singleInstance),这些模式可能会导致复用已有的Activity实例。 但是用户强调“未设置启动模式”,所以默认应该是standard。那么问题可能出在: - 用户可能是在同一个Activity实例中启动自身(例如在Activity A中启动Activity A),但可能由于任务栈的管理,系统复用了同一个实例?这并不符合standard模式。 然而,根据引用[1]:ActivityStack管理TaskRecord,每个TaskRecord包含若干个ActivityRecord,每个对应一个Activity。TaskRecord相当于任务栈,根据启动模式的不同,在启动Activity时会对TaskRecord进行不同的操作。 在standard模式下,每次启动Activity都应该在同一个任务栈(如果未指定新任务)中创建一个新的实例。 因此,用户观察到的现象(只启动了一个实例)可能由以下原因引起: - 用户可能没有正确记录启动次数(例如,可能只启动了一次)。 - 可能用户启动的两次Activity,但第二次启动时,前一个Activity已经被销毁(例如,由于内存不足被系统回收,然后重新创建)?但日志中应该能看到两个创建过程。 - 或者,用户可能是在同一个Activity中启动自己,并且使用了FLAG_ACTIVITY_SINGLE_TOP等标志,但用户没有意识到。 如何启动两个实例? - 在standard模式下,连续两次启动同一个Activity(不设置任何特殊标志),应该会创建两个实例。 因此,用户的问题可能在于他没有正确地启动两次,或者有其他因素干扰。 但是,用户提到“日志显示未设置启动模式”,所以我们需要检查日志中是否有其他信息。 另外,引用[4]提到了ActivityTaskManager.getService(),这是获取系统服务代理的方法,但和启动模式没有直接关系。 建议: 1. 确保在AndroidManifest.xml中没有为该Activity设置任何启动模式(如android:launchMode),这样就是默认的standard。 2. 确保启动Activity时没有设置任何Intent标志(如Intent.FLAG_ACTIVITY_SINGLE_TOP等)。 3. 通过两次调用startActivity()来启动同一个Activity。 示例代码: 在第一个Activity中(比如MainActivity)有两个按钮,每个按钮都启动同一个SecondActivity: Button button1 = findViewById(R.id.button1); button1.setOnClickListener(v -> { startActivity(new Intent(MainActivity.this, SecondActivity.class)); }); Button button2 = findViewById(R.id.button2); button2.setOnClickListener(v -> { startActivity(new Intent(MainActivity.this, SecondActivity.class)); }); 这样点击两次按钮,应该会创建两个SecondActivity实例。 然后,用户可以通过以下方式验证: - 在SecondActivity的onCreate()中打印日志(包括this.toString(),以查看实例地址)。 - 或者通过adb shell dumpsys activity activities命令查看当前任务栈中的Activity实例。 如果用户仍然只看到一个实例,那么需要检查是否有其他因素,例如: - 是否在启动第二个Activity时,第一个Activity已经被销毁(但通常不会,因为第一个Activity在栈中,除非被显式finish())。 - 是否在SecondActivity中启动了自身,并且使用了FLAG_ACTIVITY_CLEAR_TOP等标志? 另外,引用[2]中提到了启动时间,但和实例数量无关。 引用[3]提到了启动时间点的记录,但同样和实例数量无关。 因此,结论是:在standard模式下,正常启动两次同一个Activity应该会创建两个实例。如果用户没有看到两个实例,可能是代码逻辑问题。 如果用户希望强制启动两个实例,即使是在非standard模式下(例如singleTop等),那么可以通过设置Intent标志FLAG_ACTIVITY_MULTIPLE_TASK和FLAG_ACTIVITY_NEW_TASK来启动新的任务栈,并在新的任务栈中创建实例。但是,这通常用于启动不同任务栈的实例,同一个任务栈中standard模式应该就能创建多个实例。 所以,用户的问题可能不是配置问题,而是实现问题。建议用户检查代码和日志。 但是,如果用户确实需要两个实例,并且是在不同的任务栈中,那么可以: - 在启动Activity时,设置Intent的FLAG_ACTIVITY_NEW_TASK标志,这样如果该Activity还没有在另一个任务栈中运行,则会创建一个新的任务栈并放入新的实例;如果已经存在,则不会创建新实例(除非同时设置FLAG_ACTIVITY_MULTIPLE_TASK)。 具体: - 如果希望每次启动都创建一个新的任务栈,并且在该任务栈中创建新的Activity实例,可以同时设置: intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - 这样,每次启动都会创建一个新的任务栈,并在其中创建新的Activity实例。 但是注意:这样创建的两个实例将位于不同的任务栈中,用户可能需要通过任务切换键才能看到两个不同的任务。 总结: - 默认情况下(standard模式,无特殊标志),在同一个任务栈中连续启动同一个Activity两次,会创建两个实例。 - 如果用户没有看到两个实例,请检查代码和日志,确保是两次独立的启动。 - 如果用户希望两个实例位于不同的任务栈,可以使用FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_MULTIPLE_TASK标志。 因此,回答如下:</think>### Android Activity启动模式分析 #### 问题分析 1. **默认启动模式行为** 在Android中,当未显式设置`android:launchMode`时,Activity默认使用`standard`模式[^1]。但日志显示只启动了一个实例,可能原因包括: - **任务栈(TaskRecord)复用**:系统检测到已有相同Activity的任务栈时,会复用现有实例而非创建新实例[^1] - **Intent标志影响**:即使未设置启动模式,`FLAG_ACTIVITY_SINGLE_TOP`等Intent标志可能改变默认行为 - **系统优化机制**:低内存时系统可能自动回收并重建Activity,造成"单实例"假象 2. **日志解读关键点** 观察`ActivityTaskManager`日志中以下字段: ```log I/ActivityTaskManager: Displayed com.example/.MyActivity: +1s227ms ``` - **com.example/.MyActivity**:Activity全限定名 - **时间戳**:冷/温/热启动耗时差异(冷启动>1s,热启动<500ms)[^2] - **缺失`newIntent`日志**:若未记录`onNewIntent()`调用,说明未创建新实例 #### 解决方案:启动两个实例 1. **显式设置启动模式** 在AndroidManifest.xml中配置: ```xml <activity android:name=".MyActivity" android:launchMode="standard"/> <!-- 确保设置为标准模式 --> ``` 2. **添加Intent启动标志** 在启动Activity的代码中: ```java // 启动第一个实例 Intent intent1 = new Intent(this, MyActivity.class); startActivity(intent1); // 启动第二个实例(关键配置) Intent intent2 = new Intent(this, MyActivity.class); intent2.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent2); ``` - `FLAG_ACTIVITY_NEW_TASK`:强制创建新任务栈[^1] - `FLAG_ACTIVITY_MULTIPLE_TASK`:允许多个相同类型任务栈存在 3. **验证双实例** - **日志检查**:应出现两次`Displayed`记录: ```log I/ActivityTaskManager: Displayed com.example/.MyActivity: +324ms I/ActivityTaskManager: Displayed com.example/.MyActivity: +358ms ``` - **ADB命令**:`adb shell dumpsys activity activities`查看任务栈: ```shell * TaskRecord{id1 Affinity=com.example}: #0 ActivityRecord{id1 com.example/.MyActivity} * TaskRecord{id2 Affinity=com.example}: #0 ActivityRecord{id2 com.example/.MyActivity} ``` #### 原理解释 - **任务栈机制**:每个`TaskRecord`相当于独立容器[^1],默认情况下相同Activity会被路由到同一栈 - **标志位优先级**:Intent标志的优先级高于Manifest中的启动模式设置 - **性能影响**:启动多实例会增加内存开销(每个实例约5-15MB) > **提示**:若需完全独立实例,可在Intent中添加随机数据防止复用: > ```java > intent2.putExtra("RANDOM_ID", System.currentTimeMillis()); > ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值