官网中叫 Persisting State
,状态持久化。
使用插件时,总会需要保存插件的某些数据,再重启IntelliJ工具时,能接着使用。对于插件数据,IntelliJ分成两类:
- 组件状态:某个组件显示的数据
- 私有数据:各种密码之类的敏感数据
1 处理组件状态
对于 组件 或 服务 的内部状态,IntelliJ提供了两种方式:
- PropertiesComponent:这是一个服务,用来存储临时的、不经常变动的值
- PersistentStateComponent:这是一个普通的Java接口,通过实现这个接口,来处理复杂的数值存储
1.1 PropertiesComponent
这个 Service
的使用非常简单,可以用在 Application
和 Project
级别,存储一些临时的、不经常变动的数据,如下:
// 获取Application级别数据
PropertiesComponent appProp = PropertiesComponent.getInstance();
// 获取Project级别数据
PropertiesComponent proProp = PropertiesComponent.getInstance(Project);
// 使用方式
appProp.setValue("key", "value");
String value = appProp.getValue("key");
使用起来,确实很容易
1.2 PersistentStateComponent
1.2.1 基础使用
插件中,总会用到一些复杂数据,比如:Map,这时,就会用到 PersistentStateComponent
这个接口,用起来也很简单,通常,我们只需:
- 定义一个
Service
- 实现
PersistentStateComponent
这个接口 - 使用
@com.intellij.openapi.components.State
这个注解标明存储位置
就可以了,如下:
单独状态类 :
使用Service字段 :
需要注意的地方:
- 这种方式,只会序列化
public
字段,如果要处理private
型字段,需要用到注解 - 可以使用
@com.intellij.util.xmlb.annotations.Transient
注解来排除不需要序列化的字段 - 状态类必须有一个
默认的构造函数
,再第一次加载时,要返回一个默认的状态,不能返回null - 状态类应该实现
equal
方法,如果没实现,会通过比较其中的public
字段来确认是否相等
这种方式支持的数据类型有:
- number,数字类型:int或Integer等等
- booleans,布尔类型:true或false
- string,字符串型
- collections,集合类型:如List
- maps,映射或叫字典,如:HashMap
-
1.2.2 转换器
有时需要一些类型的转换,比如 时间字符串 转换为 LocalDateTime ,此时可以使用:
com.intellij.util.xmlb.Converter
类,需要继承它@com.intellij.util.xmlb.annotations.OptionTag
或@com.intellij.util.xmlb.annotations.Attribute
类,标明使用地方
如下:
定义 :
class LocalDateTimeConverter extends Converter<LocalDateTime> {
public LocalDateTime fromString(String value) {
final long epochMilli = Long.parseLong(value);
final ZoneId zoneId = ZoneId.systemDefault();
return Instant.ofEpochMilli(epochMilli).atZone(zoneId).toLocalDateTime();
}
public String toString(LocalDateTime value) {
final ZoneId zoneId = ZoneId.systemDefault();
final long toEpochMilli = value.atZone(zoneId).toInstant().toEpochMilli();
return Long.toString(toEpochMilli);
}
}
使用 :
class State {
@OptionTag(converter = LocalDateTimeConverter.class)
public LocalDateTime dateTime;
}
1.2.3 声明存储位置
通过使用 @com.intellij.openapi.components.State
这个注解来指定数据的存储位置,需要指定以下几个值:
- name,必须的,指定
State
的名称,也是存储的xml
的根节点 - storages,非必须的,指定了存储文件的位置,可以包含多个存储位置
- reloadable,非必须的,如果设置成false,当存储
xml
文件在外部被修改时,而且State
也被改变时,要重启整个项目或应用
对于上面的 storages
属性,它包含了 @Storage
属性,通常有以下用法:
@Storage("yourName.xml")
,直接指定文件的存储位置@Storage(StoragePathMacros.WORKSPACE_FILE)
,存储到工作空间
其他的注解:
注解 | 说明 |
---|---|
参考
https://jetbrains.org/intellij/sdk/docs/basics/persisting_state_of_components.html