22

我偶然发现了一个非常有趣的依赖注入库,名为ButterKnife. 使用ButterKnife它很容易将视图注入到活动或片段中。

class ExampleActivity extends Activity {
  @InjectView(R.id.title) TextView title;
  @InjectView(R.id.subtitle) TextView subtitle;
  @InjectView(R.id.footer) TextView footer;

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.simple_activity);
    ButterKnife.inject(this);
    // TODO Use "injected" views...
  }
}

但是,如果使用依赖注入,这些视图必须public能够Butterknife注入它(使用private字段会导致异常fields must not be private or static)。

在我过去的项目中,我总是制作所有成员字段(包括视图)private,因为我认为这是最佳实践(信息隐藏等)。现在我想知道是否有理由不制作所有视图public?在这种情况下,我不能使用ButterKnife,但我想使用它,因为它大大简化了代码。

4

1 回答 1

44

首先,Butter Knife 不是依赖注入库。您可以将其视为样板缩减库,因为它所做的只是替换findViewById和各种setXxxListener调用。

Butter Knife 要求视图不是私有的原因是它实际上生成了设置字段的代码。它生成的代码与您的类位于同一个包中,这就是该字段必须是包私有、受保护或公共的原因。如果该字段是私有的,则生成的代码将无法编译,因为它无法访问私有字段。

生成的代码如下所示:

public static void inject(ExampleActivity target, ExampleActivity source) {
  target.title = (TextView) source.findViewById(R.id.title);
  target.subtitle = (TextView) source.findViewById(R.id.subtitle);
  target.footer = (TextView) source.findViewById(R.id.footer);
}

当您调用ButterKnife.inject(this)它时,查找此生成类并inject使用您的实例调用该方法,ExampleActivity作为字段的目标和findViewById调用的源。

于 2014-12-02T08:33:17.657 回答