背景
开发的插件点击后UI卡住,怀疑是阻塞了UI线程。。。。仔细看下文档
文档翻译-Action的实现
自定义的action类是派生自抽象类 AnAction
的子类。当用户操作菜单项或工具栏按钮时,IDEA会调用action的方法
基于 AnAction
的类不能包含任何属性,因为 AnAction
的实例会存在 application整个生命周期。如果 AnAction
类使用了属性存储了短声明周期的数据但没有合理的清除,会造成内存泄漏。例如如果你把Project对象存到了这里,当用户关闭了这个Project之后就会发生内存泄漏
方法Override覆盖原则
每个action可以覆盖 AnAction.update()
,必须覆盖AnAction.actionPerformed()
.
AnAction.update()
用来被IDEA调用更新action的状态,action是否可用/是否可见取决于action在当前UI上是否可用.AnActionEvent
对象会传递给这个方法并且包含当前action上下文的信息。可以通过修改和事件上下文关联的Presentation
对象状态来改变action是否可用。像Overriding the AnAction.update()
Method说的一样, update()
方法的执行速度非常重要
2022.3+版本后AnAction.getActionUpdateThread()
返回 ActionUpdateThread
线程决定了 update()
方法是否在 background thread (BGT) or the event-dispatching thread (EDT)上被调用。首选的方式是在BGT上执行update方法, 这样可以保证application侧读取 PSI, the virtual file system (VFS), 或 project models的有利条件。在BGT上运行update的Actions不应该直接访问Swing 组件的结构。 反之EDT上运行的update的Action必须禁止访问PSI, VFS, 或 project的数据,但可以访问Swing组件和其他UI模型。所有由DataContext
提供的可访问数据在这里有说明 Determining the Action Context. 当必须从BGT切换回EDT时,需要使用 AnActionEvent.getUpdateSession()
方法获得 UpdateSession
并调用 UpdateSession.compute()
在EDT上运行方法。从2022.3开始,插件的DevKit将会有检查
AnAction.actionPerformed()
将会在可用之后当用户选择action时被IDEA调用。这个方法是实现action最麻烦的任务,它包含了当action被调用时要执行的代码。 actionPerformed()
方法也接收一个 AnActionEvent
作为参数,它用来访问任何上下文相关的信息例如 projects, files, selection。。。参考Overriding the AnAction.actionPerformed()
Method 获取更多信息
这里还有其他的方法可以在 AnAction
类中被覆盖,例如改变action默认的 Presentation
。还有一个使用场景可以通过覆盖构造器来达成,当动态注册到分组的时候demo可以在这里看到Grouping Actions
AnAction.update
IDEA会周期性的调用AnAction.update()
方法来响应用户的操作。 update()
方法用于动态判断action在当前上下文是否应该禁用或启用。方法的实现必须确保可用性状态和可见性状态 ,否则指定的action将会”卡住”。(译者注:这里的意思应该是从用户看来是卡住的现象,实际就是没响应任何动作)
AnAction.update()
方法可能在UI线程上频繁的调用。所以这个方法必须非常快的执行,没有必须执行的实际动作。例如检查选中的对象是否可用,但不做任何文件系统相关的动作。如果新的状态无法被快速的确定是否可用,判定过程应该在AnAction.actionPerformed()
中执行,并通知notify用户这个动作在当前上下文不能被执行
线程
//TODO
参考
https://plugins.jetbrains.com/docs/intellij/basic-action-system.html
https://plugins.jetbrains.com/docs/intellij/general-threading-rules.html#modality-and-invokelater
0 Comments