DOIFOR技术IDEA插件开发之UserDataHolder
DOIFOR技术IDEA插件开发之UserDataHolder
IDEA

IDEA插件开发之UserDataHolder

技术

昨天写了一篇关于DataProvider的文档,我们知道其作用是组件与Action之间解耦的。这是它的优点,恰好也是它的局限,因为在IDEA的插件SDK中,也只有AnActionEvent的getData方法可以使用DataProvider。那么组件与组件之间该如何解耦呢?

答案就是使用UserDataHolder!

public interface UserDataHolder {
  @Nullable  T getUserData(@NotNull Key key);
   void putUserData(@NotNull Key key, @Nullable T value);
}

为什么说UserDataHolder可以用于组件之间进行数据解耦?主要是Application和Project都实现了该接口,而且恰恰一个插件中组件中必然能获取到Application对象,如果是Project级别的组件,那么还能获取到Project对象,这两个在对象在对应的Scope内都是单例唯一的。

从UserDataHolder的源码可以看出,它其实就是一个类似Map的KV存储。用户在想要将数据传递给另一个组件的时候,只需要将数据存储到合适的Scope对象中,然后在另一个组件中获取Scope对象,然后调用getUserData即可。

使用方法很简单,在产生数据的地方使用Application或者Project对象的putuserData存入数据,在使用的数据的地方调用对应的getUserData即可,Key类是一个泛型类,可以在通过key来确定对应数据类型,示例如下:

public class ComponentA {
    // 定义一个Key,用于存储当前用户的名称
    public static final Key USER_NAME_KEY = Key.create("username");
    public ComponentA() {

        // 在Application级别中保存数据
        Application application = ApplicationManager.getInstance();
        application.putUserData(USER_NAME_KEY, "Tom");
    }
}

public class ComponentB {
    public void  display(){
        Application application = ApplicationManager.getInstance();
        application.getUserData(ComponentA.USER_NAME_KEY)
    }
}

将上述代码中的application换成project依然可行,使用方法大致如此。

但是注意,由于其不会自动清除数据,因此生命后期等同于对应的Scope对象,因此如果过度依赖这种方法可能会导致内存溢出。

其次,由于写和读可能发生在任意位置,所以在使用的时候,尽可能遵循某种规则,一边后期排查问题。比如可以将Key定义在存数据的地方;只在一个地方写入等等。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注