GLib.Notification带非空VariantType参数时无法激活动作如何解决?
问题根因
该错误核心是通知动作传递的Variant参数类型与注册SimpleAction时声明的参数类型不匹配,GLib对Variant类型校验非常严格,只要类型标识字节序列不一致就会触发断言失败。
修复方案
按优先级依次尝试:
- 调整动作注册的参数类型为元组包裹的字符串
绝大多数桌面环境的通知守护进程在传递动作目标值时,会自动将单个Variant值包裹进元组结构中,原来声明的STRING(类型标识s)和实际传入的(s)类型不匹配。
同时建议将动作注册逻辑从activate()迁移到startup()生命周期方法中,activate()会在应用每次被前台激活时重复执行,容易造成动作重复注册的异常。
修改后代码如下:
public class MyApplication : Gtk.Application { protected override void startup () { base.startup(); // ... // 把参数类型从GLib.VariantType.STRING改为"(s)" var show_chat_view_action = new GLib.SimpleAction ("action-show-chat-view", GLib.VariantType("(s)")); show_chat_view_action.activate.connect ((parameter) => { debug ("beep boop"); // 先取元组的第0个元素,再读取字符串值 debug (parameter.get_child_value(0).get_string ()); }); add_action (show_chat_view_action); // ... } }
通知发送的原有代码不需要修改,即可正常运行。
- 备选方案:使用字符串格式的动作声明
如果第一种方案不生效,可以不用set_default_action_and_target_value方法,直接用字符串格式指定带参数的动作:
var notification = new GLib.Notification ("Hello, world"); // 直接在动作名后用括号包裹参数,字符串参数用单引号引住 notification.set_default_action ("app.action-show-chat-view('foobar')"); app.send_notification (null, notification);
这种写法GLib会自动解析参数类型,自动适配元组包装的逻辑。
内容的提问来源于stack exchange,提问作者avojak
相关产品推荐
相关产品推荐

