当前位置: 首页 > wzjs >正文

购物类网站首页效果图网络营销广告案例

购物类网站首页效果图,网络营销广告案例,公司注册地址和办公地址不一样,好的网站搭建公司BroadcastReceiver的应用 本文是Android四大组件系列的第四篇,主要介绍BroadcastReceiver的基本概念、使用方式以及实际应用场景。 一、BroadcastReceiver基础概念 BroadcastReceiver(广播接收器)是Android四大组件之一,主要用于…

BroadcastReceiver的应用

本文是Android四大组件系列的第四篇,主要介绍BroadcastReceiver的基本概念、使用方式以及实际应用场景。

一、BroadcastReceiver基础概念

BroadcastReceiver(广播接收器)是Android四大组件之一,主要用于接收和响应系统或应用发出的广播消息。它允许应用程序接收来自Android系统或其他应用程序的通知,从而实现组件间的松耦合通信。

1.1 BroadcastReceiver的特点

  • 松耦合通信:发送方和接收方无需直接关联,通过Intent进行通信
  • 全局事件处理:可以接收系统级别的广播事件,如开机启动、网络变化等
  • 跨应用通信:可以接收来自其他应用的广播消息
  • 生命周期短:广播接收器只在处理广播消息时激活,处理完成后即销毁

1.2 广播的分类

按发送方式分类
  • 标准广播(Normal Broadcast):完全异步,所有接收器几乎同时接收到广播
  • 有序广播(Ordered Broadcast):按照优先级顺序传递,前面的接收器可以截断广播
按注册方式分类
  • 静态注册:在AndroidManifest.xml中注册,应用未启动时也能接收广播
  • 动态注册:在代码中注册,随组件生命周期变化,需要手动注销
按作用范围分类
  • 系统广播:由Android系统发出的广播,如开机、电量变化等
  • 应用内广播:在应用内部发送和接收的广播
  • 跨应用广播:可以被其他应用接收的广播

二、BroadcastReceiver的使用方式

2.1 创建BroadcastReceiver

创建BroadcastReceiver需要继承BroadcastReceiver类并实现onReceive()方法:

public class MyReceiver extends BroadcastReceiver {private static final String TAG = "MyReceiver";@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();Log.d(TAG, "Received broadcast: " + action);// 获取广播中的数据String data = intent.getStringExtra("data");// 处理广播消息if ("com.example.MY_ACTION".equals(action)) {// 处理自定义广播Toast.makeText(context, "Received: " + data, Toast.LENGTH_SHORT).show();} else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {// 处理系统广播Log.d(TAG, "System boot completed");}}
}

2.2 静态注册BroadcastReceiver

在AndroidManifest.xml中注册广播接收器:

<receiverandroid:name=".MyReceiver"android:exported="true"><intent-filter><!-- 自定义广播 --><action android:name="com.example.MY_ACTION" /><!-- 系统广播 --><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter>
</receiver>

注意:从Android 8.0(API级别26)开始,大多数隐式广播(没有明确指定接收器的广播)无法通过静态注册的方式接收,需要使用动态注册。

2.3 动态注册BroadcastReceiver

在代码中动态注册和注销广播接收器:

public class MainActivity extends AppCompatActivity {private MyReceiver myReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 创建广播接收器实例myReceiver = new MyReceiver();}@Overrideprotected void onStart() {super.onStart();// 注册广播接收器IntentFilter filter = new IntentFilter();filter.addAction("com.example.MY_ACTION");filter.addAction(Intent.ACTION_BATTERY_LOW);registerReceiver(myReceiver, filter);}@Overrideprotected void onStop() {super.onStop();// 注销广播接收器unregisterReceiver(myReceiver);}
}

2.4 发送广播

发送标准广播
// 创建Intent对象
Intent intent = new Intent("com.example.MY_ACTION");// 添加数据
intent.putExtra("data", "Hello Broadcast");// 发送广播
sendBroadcast(intent);
发送有序广播
// 创建Intent对象
Intent intent = new Intent("com.example.MY_ORDERED_ACTION");// 添加数据
intent.putExtra("data", "Hello Ordered Broadcast");// 发送有序广播
sendOrderedBroadcast(intent, null); // 第二个参数是权限

2.5 本地广播(LocalBroadcastManager)

本地广播只在应用内部传递,更加安全高效:

// 创建LocalBroadcastManager实例
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);// 注册本地广播接收器
IntentFilter filter = new IntentFilter("com.example.LOCAL_ACTION");
localBroadcastManager.registerReceiver(myReceiver, filter);// 发送本地广播
Intent intent = new Intent("com.example.LOCAL_ACTION");
intent.putExtra("data", "Hello Local Broadcast");
localBroadcastManager.sendBroadcast(intent);// 注销本地广播接收器
localBroadcastManager.unregisterReceiver(myReceiver);

注意:LocalBroadcastManager已在AndroidX中被废弃,推荐使用LiveData、Flow或其他替代方案。

三、实战案例:网络状态监听

3.1 创建网络状态广播接收器

public class NetworkReceiver extends BroadcastReceiver {private NetworkCallback networkCallback;public interface NetworkCallback {void onNetworkChanged(boolean isConnected, String networkType);}public NetworkReceiver(NetworkCallback callback) {this.networkCallback = callback;}@Overridepublic void onReceive(Context context, Intent intent) {if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {// 检查网络连接状态boolean isConnected = false;String networkType = "unknown";ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo activeNetwork = cm.getActiveNetworkInfo();if (activeNetwork != null && activeNetwork.isConnected()) {isConnected = true;if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {networkType = "WiFi";} else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {networkType = "Mobile";}}// 通知回调if (networkCallback != null) {networkCallback.onNetworkChanged(isConnected, networkType);}}}
}

3.2 在Activity中使用网络状态监听

public class MainActivity extends AppCompatActivity implements NetworkReceiver.NetworkCallback {private NetworkReceiver networkReceiver;private TextView networkStatusText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);networkStatusText = findViewById(R.id.network_status);// 创建网络状态接收器networkReceiver = new NetworkReceiver(this);}@Overrideprotected void onStart() {super.onStart();// 注册网络状态接收器IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);registerReceiver(networkReceiver, filter);// 立即检查当前网络状态checkNetworkStatus();}@Overrideprotected void onStop() {super.onStop();// 注销网络状态接收器unregisterReceiver(networkReceiver);}@Overridepublic void onNetworkChanged(boolean isConnected, String networkType) {// 更新UI显示网络状态if (isConnected) {networkStatusText.setText("Connected to " + networkType);networkStatusText.setTextColor(Color.GREEN);} else {networkStatusText.setText("No network connection");networkStatusText.setTextColor(Color.RED);}}private void checkNetworkStatus() {ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo activeNetwork = cm.getActiveNetworkInfo();boolean isConnected = activeNetwork != null && activeNetwork.isConnected();String networkType = "unknown";if (isConnected) {if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {networkType = "WiFi";} else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {networkType = "Mobile";}}onNetworkChanged(isConnected, networkType);}
}

3.3 适配Android 7.0及以上版本

Android 7.0(API级别24)及以上版本对广播接收器有一些限制,特别是对于系统广播。对于网络状态监听,可以使用NetworkCallback替代广播接收器:

public class NetworkMonitor {private ConnectivityManager connectivityManager;private NetworkCallback networkCallback;public interface NetworkStatusCallback {void onNetworkAvailable();void onNetworkLost();}public NetworkMonitor(Context context, final NetworkStatusCallback callback) {connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// 使用NetworkCallback(Android 7.0及以上)networkCallback = new ConnectivityManager.NetworkCallback() {@Overridepublic void onAvailable(Network network) {if (callback != null) {callback.onNetworkAvailable();}}@Overridepublic void onLost(Network network) {if (callback != null) {callback.onNetworkLost();}}};}}public void register() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// 注册NetworkCallbackNetworkRequest request = new NetworkRequest.Builder().build();connectivityManager.registerNetworkCallback(request, networkCallback);}}public void unregister() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && networkCallback != null) {// 注销NetworkCallbackconnectivityManager.unregisterNetworkCallback(networkCallback);}}
}

四、常见系统广播及应用场景

4.1 系统启动相关广播

  • ACTION_BOOT_COMPLETED:系统启动完成
    • 应用场景:启动后台服务、初始化应用数据
    • 权限要求:需要RECEIVE_BOOT_COMPLETED权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  • ACTION_SHUTDOWN:系统关机
    • 应用场景:保存重要数据、释放资源

4.2 电源管理相关广播

  • ACTION_BATTERY_LOW:电池电量低

    • 应用场景:提醒用户、降低应用耗电
  • ACTION_BATTERY_OKAY:电池电量恢复正常

    • 应用场景:恢复正常功能
  • ACTION_POWER_CONNECTED:连接电源

    • 应用场景:开始执行耗电任务
  • ACTION_POWER_DISCONNECTED:断开电源

    • 应用场景:停止耗电任务、进入省电模式

4.3 网络相关广播

  • CONNECTIVITY_ACTION:网络连接状态变化

    • 应用场景:监控网络状态、调整应用行为
    • 注意:Android 7.0后需要动态注册
  • WIFI_STATE_CHANGED_ACTION:WiFi状态变化

    • 应用场景:监控WiFi开关状态

4.4 应用安装相关广播

  • ACTION_PACKAGE_ADDED:应用安装

    • 应用场景:监控新应用安装
  • ACTION_PACKAGE_REMOVED:应用卸载

    • 应用场景:清理相关数据
  • ACTION_PACKAGE_REPLACED:应用更新

    • 应用场景:检测应用更新,执行迁移操作

五、实战案例:应用内消息推送系统

5.1 创建消息广播发送器

public class MessagePushManager {private static final String ACTION_NEW_MESSAGE = "com.example.ACTION_NEW_MESSAGE";private Context context;public MessagePushManager(Context context) {this.context = context.getApplicationContext();}public void sendMessage(String title, String content, String targetScreen) {Intent intent = new Intent(ACTION_NEW_MESSAGE);intent.putExtra("title", title);intent.putExtra("content", content);intent.putExtra("target_screen", targetScreen);intent.putExtra("timestamp", System.currentTimeMillis());// 使用LocalBroadcastManager发送应用内广播LocalBroadcastManager.getInstance(context).sendBroadcast(intent);}
}

5.2 创建消息广播接收器

public class MessageReceiver extends BroadcastReceiver {private static final String ACTION_NEW_MESSAGE = "com.example.ACTION_NEW_MESSAGE";private MessageListener listener;public interface MessageListener {void onNewMessage(String title, String content, String targetScreen, long timestamp);}public MessageReceiver(MessageListener listener) {this.listener = listener;}public static IntentFilter getIntentFilter() {return new IntentFilter(ACTION_NEW_MESSAGE);}@Overridepublic void onReceive(Context context, Intent intent) {if (ACTION_NEW_MESSAGE.equals(intent.getAction()) && listener != null) {String title = intent.getStringExtra("title");String content = intent.getStringExtra("content");String targetScreen = intent.getStringExtra("target_screen");long timestamp = intent.getLongExtra("timestamp", 0);listener.onNewMessage(title, content, targetScreen, timestamp);}}
}

5.3 在Activity中使用消息系统

public class MainActivity extends AppCompatActivity implements MessageReceiver.MessageListener {private MessageReceiver messageReceiver;private MessagePushManager pushManager;private TextView messageView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);messageView = findViewById(R.id.message_view);pushManager = new MessagePushManager(this);messageReceiver = new MessageReceiver(this);// 发送测试消息按钮findViewById(R.id.btn_send_message).setOnClickListener(v -> {pushManager.sendMessage("测试标题", "这是一条测试消息内容", "MainActivity");});}@Overrideprotected void onStart() {super.onStart();// 注册消息接收器LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, MessageReceiver.getIntentFilter());}@Overrideprotected void onStop() {super.onStop();// 注销消息接收器LocalBroadcastManager.getInstance(this).unregisterReceiver(messageReceiver);}@Overridepublic void onNewMessage(String title, String content, String targetScreen, long timestamp) {// 处理接收到的消息if ("MainActivity".equals(targetScreen) || targetScreen == null) {String formattedTime = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(new Date(timestamp));String message = String.format("[%s] %s\n%s", formattedTime, title, content);messageView.append(message + "\n\n");// 自动滚动到底部final ScrollView scrollView = (ScrollView) messageView.getParent();scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN));}}
}

六、常见面试题解析

6.1 BroadcastReceiver相关面试题

问题1:BroadcastReceiver的两种注册方式有什么区别?

答案

  1. 静态注册

    • 在AndroidManifest.xml中声明
    • 应用未启动时也能接收广播
    • 应用被杀死后仍能接收广播
    • Android 8.0后对隐式广播有限制
    • 生命周期与应用生命周期无关
  2. 动态注册

    • 在代码中通过registerReceiver()方法注册
    • 只有在应用运行时才能接收广播
    • 必须在组件销毁前调用unregisterReceiver()注销
    • 生命周期与注册的组件生命周期相关
    • 可以接收所有类型的广播

问题2:标准广播和有序广播有什么区别?

答案

  1. 标准广播(Normal Broadcast)

    • 完全异步执行
    • 所有接收器几乎同时接收到广播
    • 效率高
    • 接收器之间互不干扰
    • 无法被拦截
    • 通过sendBroadcast()方法发送
  2. 有序广播(Ordered Broadcast)

    • 同步执行
    • 按照接收器优先级顺序传递
    • 优先级通过intent-filter的android:priority属性设置
    • 前面的接收器可以修改广播内容
    • 可以被拦截(abortBroadcast())
    • 通过sendOrderedBroadcast()方法发送

问题3:如何在BroadcastReceiver中执行耗时操作?

答案
BroadcastReceiver的onReceive()方法在主线程中执行,不应该执行耗时操作。处理耗时任务的方法有:

  1. 启动Service:在onReceive()中启动Service处理耗时任务

    Intent serviceIntent = new Intent(context, MyService.class);
    context.startService(serviceIntent);
    
  2. 使用WorkManager:调度后台任务

    OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWorker.class).build();
    WorkManager.getInstance(context).enqueue(workRequest);
    
  3. 使用goAsync():获取PendingResult延长生命周期

    @Override
    public void onReceive(Context context, Intent intent) {final PendingResult pendingResult = goAsync();new Thread(() -> {// 执行耗时操作// ...pendingResult.finish();}).start();
    }
    

问题4:Android 8.0对广播接收器有哪些限制?如何适配?

答案
Android 8.0(API 26)对广播接收器的主要限制:

  1. 隐式广播限制:大多数隐式广播(没有明确指定接收器的广播)无法通过静态注册的方式接收

  2. 例外情况

    • 面向特定应用的显式广播
    • 特定系统广播(如BOOT_COMPLETED、ACTION_LOCALE_CHANGED等)
  3. 适配方法

    • 使用动态注册替代静态注册
    • 使用JobScheduler或WorkManager替代部分广播场景
    • 对于自定义广播,使用显式Intent指定接收器
    • 使用Context.sendBroadcast(Intent, String)方法发送带权限的广播

6.2 实际开发中的广播问题

问题1:如何防止应用外的广播干扰应用内的广播?

答案

  1. 使用LocalBroadcastManager(已废弃但仍可用)
  2. 使用自定义权限
    <!-- 在AndroidManifest.xml中定义权限 -->
    <permission android:name="com.example.MY_PERMISSION" android:protectionLevel="signature" /><!-- 在接收器中使用权限 -->
    <receiver android:name=".MyReceiver" android:permission="com.example.MY_PERMISSION" />
    
  3. 使用显式Intent:明确指定接收器组件
  4. 使用其他通信机制:如LiveData、EventBus等

问题2:如何在应用被杀死后仍能接收广播?

答案

  1. 使用静态注册:在AndroidManifest.xml中注册接收器
  2. 处理系统限制
    • 针对Android 8.0+,只能接收特定系统广播
    • 可能需要申请自启动权限(不同厂商有不同策略)
  3. 替代方案
    • 使用FCM(Firebase Cloud Messaging)
    • 使用WorkManager的周期性任务
    • 使用前台服务保持应用活跃

七、开源项目实战分析

7.1 分析EventBus中的广播机制

EventBus是一个流行的事件总线库,它的实现原理与BroadcastReceiver类似,但更加轻量和高效:

// EventBus简化实现
public class SimpleEventBus {private Map<Class<?>, List<Subscription>> subscriptionsByEventType = new HashMap<>();// 注册订阅者public void register(Object subscriber) {Class<?> subscriberClass = subscriber.getClass();// 通过反射找到所有带@Subscribe注解的方法List<SubscriberMethod> methods = findSubscriberMethods(subscriberClass);for (SubscriberMethod method : methods) {subscribe(subscriber, method);}}// 添加订阅private void subscribe(Object subscriber, SubscriberMethod method) {Class<?> eventType = method.eventType;Subscription subscription = new Subscription(subscriber, method);List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);if (subscriptions == null) {subscriptions = new ArrayList<>();subscriptionsByEventType.put(eventType, subscriptions);}subscriptions.add(subscription);}// 发布事件(类似于发送广播)public void post(Object event) {Class<?> eventClass = event.getClass();List<Subscription> subscriptions = subscriptionsByEventType.get(eventClass);if (subscriptions != null) {for (Subscription subscription : subscriptions) {postToSubscriber(subscription, event);}}}// 向订阅者发送事件private void postToSubscriber(Subscription subscription, Object event) {try {subscription.method.method.invoke(subscription.subscriber, event);} catch (Exception e) {e.printStackTrace();}}// 注销订阅者public void unregister(Object subscriber) {// 从所有事件类型的订阅列表中移除该订阅者for (List<Subscription> subscriptions : subscriptionsByEventType.values()) {Iterator<Subscription> iterator = subscriptions.iterator();while (iterator.hasNext()) {if (iterator.next().subscriber == subscriber) {iterator.remove();}}}}// 订阅信息类private static class Subscription {final Object subscriber;final SubscriberMethod method;Subscription(Object subscriber, SubscriberMethod method) {this.subscriber = subscriber;this.method = method;}}// 订阅方法类private static class SubscriberMethod {final Method method;final Class<?> eventType;SubscriberMethod(Method method, Class<?> eventType) {this.method = method;this.eventType = eventType;}}
}

与BroadcastReceiver相比,EventBus有以下特点:

  1. 完全在应用内部使用,不涉及系统广播
  2. 基于反射实现,不需要显式注册IntentFilter
  3. 支持更细粒度的事件类型(基于类型而非Action字符串)
  4. 性能更高,没有系统开销

7.2 分析RxJava中的事件处理机制

RxJava也可以用于替代BroadcastReceiver实现应用内通信:

// 创建事件总线
public class RxBus {private static final RxBus INSTANCE = new RxBus();private final Subject<Object> bus = PublishSubject.create().toSerialized();private RxBus() {// 私有构造函数}public static RxBus getInstance() {return INSTANCE;}// 发送事件public void post(Object event) {bus.onNext(event);}// 订阅事件public <T> Observable<T> toObservable(Class<T> eventType) {return bus.ofType(eventType);}
}// 使用示例
public class MainActivity extends AppCompatActivity {private Disposable subscription;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 订阅事件subscription = RxBus.getInstance().toObservable(MessageEvent.class).observeOn(AndroidSchedulers.mainThread()).subscribe(event -> {// 处理接收到的事件Toast.makeText(this, event.getMessage(), Toast.LENGTH_SHORT).show();});// 发送事件按钮findViewById(R.id.btn_send).setOnClickListener(v -> {RxBus.getInstance().post(new MessageEvent("Hello RxBus!"));});}@Overrideprotected void onDestroy() {super.onDestroy();// 取消订阅if (subscription != null && !subscription.isDisposed()) {subscription.dispose();}}// 事件类public static class MessageEvent {private String message;public MessageEvent(String message) {this.message = message;}public String getMessage() {return message;}}
}

八、总结

BroadcastReceiver是Android中用于接收广播消息的重要组件,它提供了一种松耦合的通信机制,使应用能够响应系统事件或其他应用发出的广播。

在实际开发中,我们需要根据不同场景选择合适的广播接收方式:

  1. 系统广播:使用动态注册方式,在应用运行期间接收系统事件
  2. 应用内通信:考虑使用LiveData、EventBus等替代方案,性能更好
  3. 跨应用通信:使用显式广播并添加权限控制,确保安全性

随着Android版本的更新,广播接收器的使用受到了越来越多的限制,特别是在Android 8.0及以上版本。开发者需要了解这些限制并采取适当的适配措施,如使用动态注册替代静态注册,或使用其他组件(如JobScheduler、WorkManager)替代部分广播场景。

总的来说,BroadcastReceiver是Android系统中不可或缺的组件,合理使用它可以帮助我们构建响应性更强、交互更灵活的应用程序。

http://www.dtcms.com/wzjs/31440.html

相关文章:

  • 永嘉网站制作哪家好seo网站优化系统
  • 长沙有什么好吃的河南平价的seo整站优化定制
  • 网页建设培训机构重庆官网seo分析
  • 高邮住房和城乡建设委员会网站自己做的网址如何推广
  • 网站出现的的问题网络营销策略
  • c 做网站开发东莞优化网站制作
  • 网站后台管理系统毕业论文百度入口的链接
  • 招牌做的好的网站网站推广是什么意思
  • 郑州企业自助建站系统网站和网页的区别
  • 手机网站可以做英文版本吗手机制作网站app
  • 中国住房和城乡建设网网站广州网站排名专业乐云seo
  • weekly做网站推广软文
  • 石家庄建行网站优化大师软件大全
  • wordpress做付费内容郑州seo招聘
  • 怎么做卖外挂网站免费的冬镜seo
  • 专业的外贸行业网站模板最近国际新闻大事
  • 怎么做单页竞价网站app运营
  • 网站开发哪里可做私活厦门关键词优化平台
  • 网站做seo有什么作用广州seo关键词优化费用
  • www网站建设seo是什么意思新手怎么做seo
  • 南山网站建设网络营销策略的定义
  • 政府高度重视门户网站建设的理由提交百度收录
  • 中国广东手机网站建设域名注册平台
  • 网站域名空间租用合同惠州市seo广告优化营销工具
  • 台湾wordpress重庆搜索引擎seo
  • html网站开头怎么做的制作网站的app
  • 武汉网站建设的公司哪家好宁波seo企业推广
  • 沈阳网站建设找德泰诺凡科网免费建站官网
  • 大通县wap网站建设公司网站seo优化建议
  • wordpress 头条主题seo优化排名是什么