# Intent详解

## 目录
- [Intent类型](#intent类型)
- [Intent组件](#intent组件)
- [Intent过滤器](#intent过滤器)
- [Intent传递数据](#intent传递数据)
- [Intent Flag](#intent-flag)
- [隐式Intent与显式Intent](#隐式intent与显式intent)
- [Intent最佳实践](#intent最佳实践)
- [面试常见问题](#面试常见问题)

---

## Intent类型

### 显式 Intent

```java
// 显式 Intent：明确指定目标组件
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);

// 或
Intent intent = new Intent();
intent.setComponent(new ComponentName(this, MainActivity.class));
startActivity(intent);
```

### 隐式 Intent

```java
// 隐式 Intent：通过 Action 和 Category 匹配
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.example.com"));
startActivity(intent);
```

---

## Intent组件

### ComponentName

```java
// 指定组件
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.package", 
    "com.example.package.MainActivity"));
startActivity(intent);

// 或
ComponentName component = new ComponentName(this, MainActivity.class);
Intent intent = new Intent();
intent.setComponent(component);
startActivity(intent);
```

### Class

```java
// 直接指定类
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
```

---

## Intent过滤器

### IntentFilter 配置

```xml
<!-- AndroidManifest.xml -->
<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="https" />
    </intent-filter>
</activity>
```

### Action

```java
// 常用 Action
Intent.ACTION_VIEW          // 查看
Intent.ACTION_SEND          // 发送
Intent.ACTION_EDIT          // 编辑
Intent.ACTION_DIAL          // 拨号
Intent.ACTION_CALL          // 打电话
Intent.ACTION_PICK          // 选择
Intent.ACTION_GET_CONTENT   // 获取内容
```

### Category

```java
// 常用 Category
Intent.CATEGORY_DEFAULT     // 默认
Intent.CATEGORY_LAUNCHER    // 启动器
Intent.CATEGORY_BROWSABLE   // 可浏览
Intent.CATEGORY_OPENABLE    // 可打开
```

### Data

```java
// Data 匹配
<data
    android:scheme="https"
    android:host="www.example.com"
    android:path="/path"
    android:mimeType="text/plain" />

// 使用
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.example.com/path"));
startActivity(intent);
```

---

## Intent传递数据

### 基本数据类型

```java
// 传递基本数据
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("name", "John");
intent.putExtra("age", 25);
intent.putExtra("isVip", true);
startActivity(intent);

// 接收数据
String name = getIntent().getStringExtra("name");
int age = getIntent().getIntExtra("age", 0);
boolean isVip = getIntent().getBooleanExtra("isVip", false);
```

### 对象数据

```java
// 传递对象（实现 Parcelable）
public class User implements Parcelable {
    private String name;
    private int age;
    
    // Parcelable 实现
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }
    
    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }
        
        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };
}

// 传递
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("user", user);
startActivity(intent);

// 接收
User user = getIntent().getParcelableExtra("user");
```

### Bundle

```java
// 使用 Bundle
Bundle bundle = new Bundle();
bundle.putString("name", "John");
bundle.putInt("age", 25);
intent.putExtras(bundle);

// 接收
Bundle bundle = getIntent().getExtras();
String name = bundle.getString("name");
```

---

## Intent Flag

### 常用 Flag

```java
// FLAG_ACTIVITY_NEW_TASK：在新任务栈中启动
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

// FLAG_ACTIVITY_SINGLE_TOP：等同于 singleTop
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

// FLAG_ACTIVITY_CLEAR_TOP：清除栈顶 Activity
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

// FLAG_ACTIVITY_CLEAR_TASK：清除整个任务栈
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

// FLAG_ACTIVITY_NO_HISTORY：不加入历史栈
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

// 组合使用
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
```

---

## 隐式Intent与显式Intent

### 显式 Intent

```java
// 优点：明确、快速
// 缺点：耦合度高
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
```

### 隐式 Intent

```java
// 优点：解耦、灵活
// 缺点：可能匹配多个组件
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.example.com"));
startActivity(intent);
```

### 选择建议

```java
// 应用内跳转 → 显式 Intent
Intent intent = new Intent(this, MainActivity.class);

// 调用系统功能 → 隐式 Intent
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));

// 应用间跳转 → 隐式 Intent（需要明确包名时用显式）
Intent intent = new Intent("com.example.ACTION_VIEW");
```

---

## Intent最佳实践

### 1. 数据大小限制

```java
// ❌ 错误：传递大量数据
intent.putExtra("largeData", largeByteArray); // 可能失败

// ✅ 正确：传递数据引用
intent.putExtra("dataId", dataId);
// 通过 ID 获取数据
```

### 2. 使用 Parcelable

```java
// ✅ 推荐：实现 Parcelable
public class User implements Parcelable {
    // 实现 Parcelable
}

// ❌ 不推荐：实现 Serializable（性能差）
public class User implements Serializable {
    // 实现 Serializable
}
```

### 3. 检查 Intent 是否可用

```java
// 检查 Intent 是否可用
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.example.com"));
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(intent);
} else {
    // 处理没有可用组件的情况
}
```

---

## 面试常见问题

### Q1: Intent 的作用？

**答案：**
1. **启动组件**：启动 Activity、Service、BroadcastReceiver
2. **传递数据**：组件间传递数据
3. **组件通信**：应用内和应用间通信

### Q2: 显式 Intent 和隐式 Intent 的区别？

**答案：**
- **显式 Intent**：明确指定目标组件，直接启动
- **隐式 Intent**：通过 Action、Category、Data 匹配，系统选择组件

### Q3: Intent Filter 的匹配规则？

**答案：**
1. **Action**：必须匹配
2. **Category**：Intent 中的 Category 必须在 Filter 中存在
3. **Data**：scheme、host、path、mimeType 必须匹配

### Q4: Intent 传递数据的方式？

**答案：**
1. **putExtra**：传递基本数据类型
2. **putParcelable**：传递 Parcelable 对象
3. **putSerializable**：传递 Serializable 对象（不推荐）
4. **Bundle**：使用 Bundle 传递多个数据

---

*最后更新：2024年*
