社团网站建设旅行社网站怎么做
2026/4/1 3:54:35 网站建设 项目流程
社团网站建设,旅行社网站怎么做,自助做网站傻瓜式自助建站工具,3d建模师未来发展前景在安卓开发中#xff0c;广播#xff08;Broadcast#xff09;是组件间通信的核心机制之一#xff0c;它像一个“系统公告栏”#xff0c;允许应用内组件、甚至跨应用间通过“发布-订阅”模式传递消息。无论是监听网络变化、接收开机完成事件#xff0c;还是实现应用内模…在安卓开发中广播Broadcast是组件间通信的核心机制之一它像一个“系统公告栏”允许应用内组件、甚至跨应用间通过“发布-订阅”模式传递消息。无论是监听网络变化、接收开机完成事件还是实现应用内模块通信广播都扮演着重要角色。但广播的使用看似简单实则暗藏诸多细节。一、广播是什么、广播的作用1. 广播的定义广播是安卓系统提供的一种跨组件、跨进程的通信机制。其核心思想是“事件驱动”当某个事件发生时如网络断开、电量低、应用安装事件源广播发送者会发送一条广播消息系统中所有注册了该广播的接收者BroadcastReceiver都会收到这条消息并执行相应的逻辑。2. 广播的核心角色广播发送者Sender发起广播的角色可以是系统组件如系统服务、第三方应用也可以是自身应用的Activity、Service等。发送广播的本质是通过Intent携带消息并调用系统API发送。广播接收者Receiver监听并处理广播的组件必须继承BroadcastReceiver类并重写onReceive(Context, Intent)方法——这是接收广播后的核心处理逻辑入口。系统服务AMSActivity Manager Service作为“中介”负责管理广播的发送与匹配。发送者将广播交给AMSAMS根据广播的Action、权限等信息匹配所有符合条件的接收者再将广播分发给它们。3. 广播的核心价值解耦组件通信发送者无需知道接收者的存在接收者也无需依赖发送者二者通过“事件”间接通信降低组件耦合度。例如应用的支付模块发送“支付成功”广播订单模块、消息模块只需注册该广播即可响应无需与支付模块直接关联。监听系统事件这是广播最常用的场景。系统会在特定事件发生时发送预设广播应用通过接收这些广播实现对系统状态的感知如监听网络变化、屏幕点亮/熄灭、电池电量等。跨进程通信广播天然支持跨进程传递例如系统的“应用安装完成”广播所有监听该事件的应用都能收到实现跨应用的协同。二、广播的分类1. 按发送方式有序广播 vs 无序广播特性无序广播Normal Broadcast有序广播Ordered Broadcast传递顺序所有接收者同时接收无固定顺序按接收者优先级排序从高到低依次传递截断能力无法截断所有接收者都能收到优先级高的接收者可调用abortBroadcast()截断后续接收者收不到数据传递接收者无法修改广播数据优先级高的接收者可通过setResultData()修改数据传递给后续接收者发送APIsendBroadcast(Intent)sendOrderedBroadcast(Intent, String)适用场景通知类消息如“新消息提醒”“天气更新”需要按顺序处理的场景如短信拦截、权限验证2. 按作用范围全局广播 vs 本地广播全局广播Global Broadcast特性广播可被系统中所有应用的接收者监听也可发送给所有应用。风险存在安全隐患如敏感数据通过广播泄露和性能问题过多应用监听可能导致广播延迟。适用场景跨应用通信、监听系统事件。本地广播Local Broadcast特性广播仅在当前应用内部传递无法跨进程由LocalBroadcastManager管理。优势安全性高避免数据泄露、效率高无需跨进程通信、无ANR风险内部使用Handler机制。适用场景应用内组件间通信如Activity向Service发送指令、Fragment与Activity传递消息。3. 按发送者系统广播 vs 自定义广播系统广播System Broadcast系统预定义的广播由系统组件发送对应特定系统事件。例如网络变化android.net.conn.CONNECTIVITY_CHANGE开机完成android.intent.action.BOOT_COMPLETED电量低android.intent.action.BATTERY_LOW自定义广播Custom Broadcast开发者自行定义Action的广播用于应用内或跨应用的自定义事件传递。例如应用内“支付成功”广播Action可定义为com.example.app.PAY_SUCCESS。三、广播接收者广播接收者BroadcastReceiver是处理广播的核心其使用流程分为“定义接收者”“注册广播”“处理广播”三步其中“注册”是关键——安卓提供两种注册方式各有适用场景。1. 定义广播接收者无论哪种注册方式接收者的定义逻辑一致继承BroadcastReceiver重写onReceive()方法。// 自定义广播接收者 public class MyBroadcastReceiver extends BroadcastReceiver { // 广播接收后回调此方法 Override public void onReceive(Context context, Intent intent) { // 1. 获取广播携带的数据 String action intent.getAction(); String data intent.getStringExtra(key); // 2. 根据Action区分不同广播执行对应逻辑 if (com.example.app.PAY_SUCCESS.equals(action)) { // 处理支付成功逻辑更新订单状态、提示用户等 Toast.makeText(context, 支付成功 data, Toast.LENGTH_SHORT).show(); } else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { // 处理网络变化逻辑 checkNetworkState(context); } } // 示例检查网络状态 private void checkNetworkState(Context context) { ConnectivityManager cm (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info cm.getActiveNetworkInfo(); if (info ! null info.isConnected()) { Toast.makeText(context, 网络已连接, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, 网络已断开, Toast.LENGTH_SHORT).show(); } } }注意onReceive()方法运行在主线程UI线程中不能执行耗时操作超过10秒会触发ANR。若需处理耗时逻辑需启动Service或使用WorkManager不能直接在该方法中开线程线程可能被系统回收。2. 注册广播核心广播接收者必须注册后才能接收广播注册分为“静态注册”和“动态注册”二者的核心差异在于“注册时机”和“生命周期关联”。方式一静态注册AndroidManifest注册在AndroidManifest.xml中配置接收者属于“全局注册”应用未启动时也能接收广播。application ... receiver android:name.MyBroadcastReceiver android:enabledtrue android:exportedtrue intent-filter action android:namecom.example.app.PAY_SUCCESS / action android:nameandroid.net.conn.CONNECTIVITY_CHANGE / /intent-filter /receiver /application uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE /说明enabled控制接收者是否启用若为false即使注册也无法接收广播。exported控制是否允许接收其他应用的广播。若为false仅能接收自身应用发送的广播提升安全性。适用场景适用于需要在应用未启动时接收的特殊系统广播如开机完成、应用安装/卸载等。API 26后的限制为了优化系统性能Android8.0API 26后除少数特殊系统广播外静态注册的接收者无法接收普通广播。方式二动态注册代码注册在Activity、Service等组件的代码中通过registerReceiver()注册广播接收者的生命周期与注册组件绑定组件销毁前必须注销否则会导致内存泄漏。public class MainActivity extends AppCompatActivity { private MyBroadcastReceiver myReceiver; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 1. 初始化接收者 myReceiver new MyBroadcastReceiver(); // 2. 配置接收的广播Action IntentFilter intentFilter new IntentFilter(); intentFilter.addAction(com.example.app.PAY_SUCCESS); // 自定义广播 intentFilter.addAction(ConnectivityManager.CONNECTIVITY_CHANGE); // 系统广播 // 若为有序广播可设置优先级-1000~1000数值越大优先级越高 intentFilter.setPriority(100); // 3. 注册广播 registerReceiver(myReceiver, intentFilter); } Override protected void onDestroy() { super.onDestroy(); // 4. 必须注销广播避免内存泄漏 unregisterReceiver(myReceiver); } }注册后只有当组件如Activity处于运行状态时接收者才能接收广播组件销毁前必须调用unregisterReceiver()注销否则系统会抛出IllegalArgumentException。但现在推荐使用 LiveData、SharedFlowKotlin或 EventBus 来替代应用内的本地广播通信。综上我们可以总结出两种注册方式的区别对比维度静态注册动态注册注册时机应用安装时由系统完成注册组件运行时如onCreate手动注册应用未启动时可接收广播API 26前无法接收生命周期与应用绑定除非卸载或禁用与注册组件绑定组件销毁需注销API 26兼容性大部分广播失效完全兼容灵活性低无法动态修改高可动态添加/移除Action3. 发送广播发送广播的核心是通过Intent指定广播的Action和携带数据再调用对应的发送API。发送无序广播// 1. 构建Intent指定广播Action Intent intent new Intent(com.example.app.PAY_SUCCESS); // 2. 携带数据键值对形式 intent.putExtra(orderId, 123456); intent.putExtra(amount, 99.0); // 3. 发送无序广播 sendBroadcast(intent); // 发送时可以带上权限字符串只有拥有该权限的接收者才能收到。 sendBroadcast(intent, com.example.PERMISSION); // 发送本地无序广播仅应用内可见 LocalBroadcastManager.getInstance(this).sendBroadcast(intent);发送有序广播Intent intent new Intent(com.example.app.SMS_RECEIVED); intent.putExtra(smsContent, 【验证码】123456); // 发送有序广播第二个参数是权限若为null所有应用均可接收 // 优先级高的接收者可截断广播 sendOrderedBroadcast(intent, null); // 有序广播的截断与数据修改示例在接收者的onReceive中 Override public void onReceive(Context context, Intent intent) { if (com.example.app.SMS_RECEIVED.equals(intent.getAction())) { // 1. 修改广播数据 setResultData(【拦截后】验证码已屏蔽); // 2. 截断广播后续接收者无法收到 abortBroadcast(); } }四、实践一下监听系统网络变化1. 声明权限!-- 访问网络状态权限 -- uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE /2. 定义广播接收者public class NetworkChangeReceiver extends BroadcastReceiver { Override public void onReceive(Context context, Intent intent) { // 适配API 23的网络状态获取方式 ConnectivityManager cm (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (Build.VERSION.SDK_INT Build.VERSION_CODES.M) { Network network cm.getActiveNetwork(); NetworkCapabilities capabilities cm.getNetworkCapabilities(network); if (capabilities ! null) { if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { sendNetworkEvent(context, WiFi网络); } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { sendNetworkEvent(context, 移动数据网络); } else { sendNetworkEvent(context, 无网络连接); } } else { sendNetworkEvent(context, 无网络连接); } } else { // 兼容低版本 NetworkInfo info cm.getActiveNetworkInfo(); if (info ! null info.isConnected()) { if (info.getType() ConnectivityManager.TYPE_WIFI) { sendNetworkEvent(context, WiFi网络); } else if (info.getType() ConnectivityManager.TYPE_MOBILE) { sendNetworkEvent(context, 移动数据网络); } } else { sendNetworkEvent(context, 无网络连接); } } } // 发送事件到Activity可通过接口或LiveData优化 private void sendNetworkEvent(Context context, String state) { if (context instanceof MainActivity) { ((MainActivity) context).onNetworkStateChanged(state); } } }3. 动态注册与注销public class MainActivity extends AppCompatActivity { private NetworkChangeReceiver networkReceiver; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 注册网络变化广播 networkReceiver new NetworkChangeReceiver(); IntentFilter intentFilter new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(networkReceiver, intentFilter); } // 接收网络状态变化事件更新UI public void onNetworkStateChanged(String state) { TextView tvNetwork findViewById(R.id.tv_network); tvNetwork.setText(当前网络 state); } Override protected void onDestroy() { super.onDestroy(); // 注销广播 unregisterReceiver(networkReceiver); } }结语广播Broadcast作为 Android 四大组件之一虽然概念诞生已久但它从未过时。从最早的肆意发送到如今 Android 8.0 的隐式限制、Android 14 的导出标志强制化广播机制的每一次演变都折射出 Android 系统对性能与安全的极致追求。对于开发者而言掌握广播不仅仅是学会写onReceive更重要的是理解其背后的设计模式与系统边界。在实际开发中我们应遵循“最小权限原则”尽量使用动态注册善用SharedFlow等现代技术替代本地广播并时刻关注系统版本的迭代差异。希望这篇文章能帮你构建起完整的广播知识体系。组件通信的方式有千万种愿你能根据场景选择最优雅的那一种。Happy Coding!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询