systemui无法加载自定义通知模板分析报告
1 关键字 SystemUI;notification;通知模板 2 问题描述 开发板型号:rk3568 内核版本: 问题现象: systemui无法加载自定义通知模板 测试步骤: 在gitee上下载systemui-master分支代码,在本地进行编译、签名、打包;使用hdc将已签名的hap包安装到搭载OpenHarmony的设备上 安装发送带模板通知的Demo,发送模板通知 3 问题原因 3.
1 关键字
SystemUI;notification;通知模板
2 问题描述
开发板型号:rk3568
内核版本:
问题现象:
-
systemui无法加载自定义通知模板
测试步骤:
-
在gitee上下载systemui-master分支代码,在本地进行编译、签名、打包;使用hdc将已签名的hap包安装到搭载OpenHarmony的设备上
-
安装发送带模板通知的Demo,发送模板通知
3 问题原因
3.1 正常机制
-
systemui接收到通知,下拉通知面板时展示模板通知
3.2 异常机制
-
systemui接收到通知,下拉通知面板无法展示通知
4 解决方案
通过自定义模块实现模板通知的展示
-
1、在features/noticeitem/src/main/ets/com/ohos/noticeItem/view/item/目录下创建自定义模块:MyCustomItem.ets,内容如下:
import Constants, {NotificationItemData, NotificationLayout as Layout} from '../../common/constants';
const TAG = 'NoticeItem-CustomItem';
@Component
export default struct MyCustomItem {
private customItemData: any = {};
aboutToAppear() {
console.log(TAG, `>>>> CustomItem aboutToAppear; customItemData = ${JSON.stringify(this.customItemData)}`);
}
build() {
Column() {
Row(){
Image(this.customItemData.smallIcon)
.objectFit(ImageFit.Contain)
.width(Layout.TITLE_IMAGE_SIZE)
.height(Layout.TITLE_IMAGE_SIZE)
Text(this.customItemData.appName)
.fontColor($r("sys.color.ohos_fa_text_primary"))
.fontSize($r("sys.float.ohos_id_text_size_body3"))
.fontWeight(FontWeight.Regular)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(Constants.SINGLE_LINE)
}
Column(){
Text(`template name: ${this.customItemData.template.name}`)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontWeight(FontWeight.Medium)
.lineHeight(Layout.TEXT_LINE_HEIGHT)
Text(`template data: ${JSON.stringify(this.customItemData.template.data)}`)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontWeight(FontWeight.Medium)
.lineHeight(Layout.TEXT_LINE_HEIGHT)
Text(this.customItemData.title)
.maxLines(Constants.SINGLE_LINE)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor("#00ff00")
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontWeight(FontWeight.Medium)
.lineHeight(Layout.TEXT_LINE_HEIGHT)
Text(this.customItemData.text)
.maxLines(Constants.SINGLE_LINE)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor("#ff00ff")
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontWeight(FontWeight.Regular)
.lineHeight(Layout.TEXT_LINE_HEIGHT)
}
}
.alignItems(HorizontalAlign.Start)
}
}
-
2、在features/noticeitem/src/main/ets/com/ohos/noticeItem/view/item/notificationItem.ets模块中修改如下代码
//import CustomItem from './customItem';
import MyCustomItem from './MyCustomItem';
... ...
if (this.itemData.template?.name) {
//CustomItem({ customItemData: this.itemData, clickAction: () => this.showDevicesDialog(), isSubItem: this.isSubItem });
MyCustomItem({ customItemData: this.itemData });
} else {
GeneralItem({ itemData: this.itemData, clickAction: () => this.showDevicesDialog(), isSubItem: this.isSubItem })
}
-
3、重新编译、打包、安装systemui
-
4、发送带模板的通知,得到如下自定义通知展示
-
5 定位过程
-
1、根据日志显示通知已发送成功
-
-
通知模板的内容是
-
-
2、根据systemui中通知的展示可知,带有模板的通知是由features/noticeitem/src/main/ets/com/ohos/noticeItem/view/item/customItem.ets组件进行渲染
Column() {
if (this.itemData.template?.name) {
//如果通知的template不为空则渲染CustomItem组件
CustomItem({ customItemData: this.itemData, clickAction: () => this.showDevicesDialog(), isSubItem: this.isSubItem });
} else {
GeneralItem({ itemData: this.itemData, clickAction: () => this.showDevicesDialog(), isSubItem: this.isSubItem })
}
}
在CustomItem组件中通过日志可以得到验证
-
3、通过CustomItem模块日志输出,可知ViewModel模块中获取到template为空
ViewModel.getPluginTempLate(this.customItemData.template.name);
-
4、ViewModel模块中getPluginComponent方法调用的是NotificationService中的方法
getPluginTempLate(templateName) {
Log.showInfo(TAG, 'getPluginTempLate: ' + templateName);
return NotificationService.getPluginTempLate(templateName)
}
-
5、通过日志可知NotificationService中getPluginComponent方法最终返回为空,也就说明NotificationManager.NotificationTemplateMap为空,即:在NotificationManager中并未对NotificationTemplateMap进行赋值
getPluginTempLate(templateName) {
Log.showInfo(TAG, `getPluginTempLate param:${templateName}`);
let pluginTempLate = null;
if (NotificationManager.NotificationTemplateMap !== null) {
pluginTempLate = NotificationManager.NotificationTemplateMap.get(templateName);
}
Log.showInfo(TAG, `getPluginTempLate pluginTempLate:${JSON.stringify(pluginTempLate)}`);
return pluginTempLate;
}
-
6、在NotificationManager中对NotificationTemplateMap进行赋值的方法如下,最终通过日志输出NotificationTemplateMap为空,表示NotificationManager对NotificationTemplateMap赋值失败
static requestTemplate(tag, ownerWant, templateName, templatePath) {
Log.showInfo(TAG, `requestTemplate from: ${tag}`);
let reqWant = {
bundleName: '',
abilityName: ''
};
let reqData = {}
let requestParam = {
owner: ownerWant,
want: reqWant,
name: templateName,
data: reqData,
jsonPath: templatePath
};
Log.showInfo(TAG, `requestTemplate requestParam: ${JSON.stringify(requestParam)}`)
NotificationManager.request(tag, requestParam, (err, data) => {
Log.showInfo(TAG, `request finished err: ${JSON.stringify(err)} data: ${JSON.stringify(data)}`)
Log.showInfo(TAG, `request finished templateData: ${templateName} data: ${JSON.stringify(data.componentTemplate)}`)
if (data?.componentTemplate?.source) {
Log.showInfo(TAG, `request finished data.componentTemplate.source:${JSON.stringify(data.componentTemplate.source)}`)
let templates = JSON.parse(data.componentTemplate.source);
Log.showInfo(TAG, `request templates: ${JSON.stringify(templates)}`)
for (let key in templates) {
NotificationManager.NotificationTemplateMap.set(key, {
"source": templates[key], "ability": ""
});
}
}
});
Log.showInfo(TAG, `NotificationManager NotificationTemplateMap: ${JSON.stringify(NotificationManager.NotificationTemplateMap)}`)
}
结论:由于NotificationTemplateMap赋值失败导致PluginComponent无法正常渲染,systemui无法加载带有模板的通知;因此可以自定义模块(不使用PluginComponent组件)来进行模板通知渲染
6 知识分享
-
有关systemui中实现notification的文档,详见通知模块在SystemUI中的实现及其使用说明
更多推荐
所有评论(0)