Files
mkdocs/docs/android面试/核心组件/BroadcastReceiver详解.md
2026-01-15 11:53:37 +08:00

7.4 KiB
Raw Permalink Blame History

BroadcastReceiver详解

目录


BroadcastReceiver类型

普通广播接收器

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 处理广播
        String action = intent.getAction();
        if ("com.example.ACTION_CUSTOM".equals(action)) {
            String data = intent.getStringExtra("data");
            // 处理数据
        }
    }
}

有序广播接收器

// 可以设置优先级和结果
public class OrderedReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 处理广播
        setResultCode(Activity.RESULT_OK);
        setResultData("Result Data");
    }
}

静态注册与动态注册

静态注册

<!-- AndroidManifest.xml -->
<receiver
    android:name=".MyReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

特点:

  • 应用安装时注册
  • 可以接收系统广播
  • 应用未运行也能接收
  • Android 8.0+ 限制静态注册

动态注册

public class MainActivity extends AppCompatActivity {
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // 处理广播
        }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.example.ACTION_CUSTOM");
        registerReceiver(receiver, filter);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }
}

特点:

  • 代码中注册
  • 需要应用运行
  • 必须手动注销
  • 更灵活

有序广播与无序广播

无序广播

// 发送无序广播
Intent intent = new Intent("com.example.ACTION_BROADCAST");
intent.putExtra("data", "value");
sendBroadcast(intent);

// 所有接收器同时接收
// 无法中断广播

有序广播

// 发送有序广播
Intent intent = new Intent("com.example.ACTION_BROADCAST");
intent.putExtra("data", "value");
sendOrderedBroadcast(intent, null);

// 接收器按优先级接收
// 可以中断广播

优先级设置

<!-- AndroidManifest.xml -->
<receiver android:name=".MyReceiver">
    <intent-filter android:priority="1000">
        <action android:name="com.example.ACTION_BROADCAST" />
    </intent-filter>
</receiver>
// 动态注册设置优先级
IntentFilter filter = new IntentFilter("com.example.ACTION_BROADCAST");
filter.setPriority(1000);
registerReceiver(receiver, filter);

中断广播

@Override
public void onReceive(Context context, Intent intent) {
    // 中断广播
    abortBroadcast();
    
    // 设置结果
    setResultCode(Activity.RESULT_OK);
    setResultData("Result");
}

系统广播

常用系统广播

// 开机完成
Intent.ACTION_BOOT_COMPLETED

// 网络状态变化
ConnectivityManager.CONNECTIVITY_ACTION

// 电池状态变化
Intent.ACTION_BATTERY_CHANGED

// 屏幕开启/关闭
Intent.ACTION_SCREEN_ON
Intent.ACTION_SCREEN_OFF

// 应用安装/卸载
Intent.ACTION_PACKAGE_ADDED
Intent.ACTION_PACKAGE_REMOVED

// 时间变化
Intent.ACTION_TIME_TICK
Intent.ACTION_TIME_CHANGED

系统广播接收

// 接收开机广播
public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            // 开机完成,启动服务
            Intent serviceIntent = new Intent(context, MyService.class);
            context.startService(serviceIntent);
        }
    }
}

自定义广播

发送自定义广播

// 发送无序广播
Intent intent = new Intent("com.example.ACTION_CUSTOM");
intent.putExtra("data", "value");
sendBroadcast(intent);

// 发送有序广播
sendOrderedBroadcast(intent, null);

// 发送本地广播LocalBroadcastManager
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

接收自定义广播

// 静态注册
<receiver android:name=".CustomReceiver">
    <intent-filter>
        <action android:name="com.example.ACTION_CUSTOM" />
    </intent-filter>
</receiver>

// 动态注册
IntentFilter filter = new IntentFilter("com.example.ACTION_CUSTOM");
registerReceiver(receiver, filter);

广播安全

安全措施

1. 限制广播接收

<!-- AndroidManifest.xml -->
<receiver
    android:name=".MyReceiver"
    android:exported="false"> <!-- 不允许其他应用发送 -->
    <intent-filter>
        <action android:name="com.example.ACTION_CUSTOM" />
    </intent-filter>
</receiver>

2. 使用权限

<!-- 发送广播需要权限 -->
<uses-permission android:name="com.example.PERMISSION" />

<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="com.example.ACTION_CUSTOM" />
    </intent-filter>
</receiver>

<!-- 发送广播 -->
sendBroadcast(intent, "com.example.PERMISSION");

3. 使用本地广播

// LocalBroadcastManager只能应用内接收
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

// 注册本地广播
LocalBroadcastManager.getInstance(this)
    .registerReceiver(receiver, filter);

BroadcastReceiver最佳实践

1. 及时注销

@Override
protected void onDestroy() {
    super.onDestroy();
    if (receiver != null) {
        unregisterReceiver(receiver);
    }
}

2. 避免耗时操作

@Override
public void onReceive(Context context, Intent intent) {
    // ❌ 错误:在 onReceive 中执行耗时操作
    // doHeavyWork();
    
    // ✅ 正确:启动 Service 执行耗时操作
    Intent serviceIntent = new Intent(context, MyService.class);
    context.startService(serviceIntent);
}

3. 使用 LocalBroadcastManager

// 应用内通信使用本地广播
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

面试常见问题

Q1: 静态注册和动态注册的区别?

答案:

  • 静态注册AndroidManifest.xml 中注册,应用安装时注册,可以接收系统广播
  • 动态注册:代码中注册,需要应用运行,必须手动注销

Q2: 有序广播和无序广播的区别?

答案:

  • 无序广播:所有接收器同时接收,无法中断
  • 有序广播:按优先级接收,可以中断

Q3: Android 8.0 对广播的限制?

答案:

  • 限制静态注册大部分广播
  • 推荐使用动态注册
  • 使用 JobScheduler 或 WorkManager 替代

Q4: 广播安全措施?

答案:

  1. 设置 android:exported="false"
  2. 使用权限保护
  3. 使用本地广播LocalBroadcastManager

最后更新2024年