Skip to main content

广播

在 Android 中实现广播功能主要有两种方式:标准广播有序广播,同时需注意静态注册与动态注册的区别。以下是完整实现方案:

一、广播基础实现

1. 创建广播接收器(BroadcastReceiver)

// 自定义广播接收器
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 获取广播传递的数据
String action = intent.getAction();
String message = intent.getStringExtra("message");

// 根据不同 action 处理逻辑
if (action.equals("com.example.MY_CUSTOM_ACTION")) {
Log.d("MyReceiver", "收到自定义广播: " + message);
}
}
}

2. 发送广播

// 发送标准广播(异步,无序接收)
Intent intent = new Intent("com.example.MY_CUSTOM_ACTION");
intent.putExtra("message", "这是一条广播消息");
sendBroadcast(intent);

// 发送有序广播(同步,按优先级接收)
sendOrderedBroadcast(intent, null);

3. 注册广播接收器

  • 动态注册(推荐,避免内存泄漏)
    public class MainActivity extends AppCompatActivity {
    private MyReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 创建接收器实例
    receiver = new MyReceiver();

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

    @Override
    protected void onDestroy() {
    super.onDestroy();
    // 务必在 Activity 销毁时取消注册
    unregisterReceiver(receiver);
    }
    }
  • 静态注册(适用于系统广播)
    <!-- AndroidManifest.xml -->
    <receiver android:name=".MyReceiver">
    <intent-filter>
    <action android:name="com.example.MY_CUSTOM_ACTION" />
    </intent-filter>
    </receiver>

二、系统广播示例(监听网络变化)

1. 创建网络状态接收器

public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
Log.d("NetworkReceiver", "网络已连接: " + networkInfo.getTypeName());
} else {
Log.d("NetworkReceiver", "网络已断开");
}
}
}

2. 注册系统广播

<!-- 需添加网络权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- 静态注册网络广播接收器 -->
<receiver android:name=".NetworkChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>

三、有序广播与结果传递

1. 设置广播优先级

// 动态注册时设置优先级(数值越大优先级越高)
IntentFilter filter = new IntentFilter("com.example.ORDERED_ACTION");
filter.setPriority(1000);
registerReceiver(receiver, filter);

2. 接收与传递结果

public class HighPriorityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 获取前一个接收器的结果
String result = getResultData();

// 修改结果并传递给下一个接收器
setResultData(result + " -> 高优先级处理");

// 终止广播(后续接收器无法接收)
// abortBroadcast();
}
}

四、LocalBroadcastManager(本地广播)

1. 优势

  • 仅在应用内传播,更安全高效。
  • 无需担心其他应用监听或篡改广播内容。

2. 使用方式

// 注册本地广播接收器
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
manager.registerReceiver(receiver, new IntentFilter("com.example.LOCAL_ACTION"));

// 发送本地广播
Intent localIntent = new Intent("com.example.LOCAL_ACTION");
manager.sendBroadcast(localIntent);

五、Android 8.0+ 后台广播限制

1. 静态注册限制

  • Android 8.0(API 26)及以上,大多数隐式广播(如 ACTION_BOOT_COMPLETED)无法通过静态注册接收。
  • 解决方案:改用动态注册或 JobScheduler

2. 示例(监听屏幕开关)

// 动态注册(Android 8.0+ 必须)
public class ScreenReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.d("ScreenReceiver", "屏幕已点亮");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.d("ScreenReceiver", "屏幕已关闭");
}
}
}

// 在 Activity 中动态注册
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ScreenReceiver receiver = new ScreenReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(receiver, filter);
}

六、注意事项

  1. 内存泄漏:动态注册的广播必须在 onDestroy() 中取消注册。
  2. 性能影响:避免在 onReceive() 中执行耗时操作(如网络请求),可通过 HandlerService 处理。
  3. 权限控制:发送自定义广播时可指定权限,确保安全性:
    // 发送带权限的广播
    sendBroadcast(intent, "com.example.MY_PERMISSION");
  4. 替代方案:复杂场景推荐使用 EventBusLiveData 实现组件间通信,减少对广播的依赖。

总结

  • 标准广播:异步、无序,适合一对多通知。
  • 有序广播:同步、按优先级处理,支持结果传递与终止。
  • 本地广播:应用内安全通信,性能更优。
  • 系统广播:需注意 Android 8.0+ 的后台限制,优先使用动态注册。

根据具体场景选择合适的广播类型,并严格遵循生命周期管理,可确保广播功能稳定可靠。