# ButterKnife原理

## 目录
- [ButterKnife原理](#butterknife原理)
- [注解处理](#注解处理)
- [代码生成](#代码生成)
- [ButterKnife源码分析](#butterknife源码分析)
- [ButterKnife最佳实践](#butterknife最佳实践)
- [面试常见问题](#面试常见问题)

---

## ButterKnife原理

### 定义

```java
// ButterKnife：视图绑定库
// 使用注解减少 findViewById
// 编译时生成代码
```

### 使用方式

```java
public class MainActivity extends AppCompatActivity {
    @BindView(R.id.textView)
    TextView textView;
    
    @OnClick(R.id.button)
    void onButtonClick() {
        // 处理点击
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }
}
```

---

## 注解处理

### 注解类型

```java
// @BindView：绑定 View
@BindView(R.id.textView)
TextView textView;

// @OnClick：点击事件
@OnClick(R.id.button)
void onButtonClick() {}

// @BindViews：绑定多个 View
@BindViews({R.id.view1, R.id.view2})
List<View> views;
```

### 编译时处理

```java
// 编译时，注解处理器扫描注解
// 生成绑定代码
// 运行时调用生成的代码
```

---

## 代码生成

### 生成的代码

```java
// 编译时生成 MainActivity_ViewBinding
public class MainActivity_ViewBinding implements Unbinder {
    private MainActivity target;
    
    public MainActivity_ViewBinding(MainActivity target, View source) {
        this.target = target;
        target.textView = source.findViewById(R.id.textView);
    }
}
```

---

## ButterKnife源码分析

### 关键类

```java
// ButterKnife：入口类
// ViewBinding：视图绑定
// Unbinder：解绑接口
```

---

## ButterKnife最佳实践

### 1. 及时解绑

```java
private Unbinder unbinder;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    unbinder = ButterKnife.bind(this);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (unbinder != null) {
        unbinder.unbind();
    }
}
```

---

## 面试常见问题

### Q1: ButterKnife 的原理？

**答案：**
- 使用注解标记 View
- 编译时生成绑定代码
- 运行时调用生成的代码

### Q2: ButterKnife 的优缺点？

**答案：**
- **优点**：减少 findViewById，代码简洁
- **缺点**：需要编译时处理，已停止维护

### Q3: ButterKnife 的替代方案？

**答案：**
- ViewBinding（官方推荐）
- DataBinding
- Kotlin 扩展

---

*最后更新：2024年*
