android广播

活跃与非活跃

每个广播接收者都实现了回调方法 void onReceive(Context curContext, Intent broadcastMsg)
广播接收者有2种状态,活跃与非活跃,在执行onReceive的时候就是活跃状态,其他时候为非活跃状态
有一个活跃的广播接收者的进程是受保护的,不会被杀死

onReceive处理耗时任务


BroadcastReceiver在10s内无法处理完成相关任务就会产生ANR
如果在onReceive要处理非常复杂的任务就可能产生ANR,因此我们想在onReceive起个子线程,交由子线程处理,onReceive先返回,这样不会产生ANR,但是BroadcastReceiver是不活跃的,进程可能被杀死,正在工作的子线程当然也会被杀死。
合适的方法是onReceive()启动一个服务,在服务中启线程做这个工作。

那为什么不直接在onReceive里启线程呢?为什么要起个service,在service里启线程呢?
其实都是可以的,只是通过service起线程要好一些,使用service会使得进程优先级高一些,至少保证在服务进程这个级别,不容易被杀死,

API11之后还有一种方法
API11以後可以調用goAsync()方法,這個方法會返回一個PendingResult對象,android系統會認為OnReceive()方法還沒有執行完成直到調用PendingResult.finish(),所以可以調用goAsync方法后,新开一个线程去执行耗時操作,執行完后調用PendingResult.finish()方法。這裡耗時的操作也不能超過10秒

有序广播和无序广播

BroadcastReceiver所对应的广播分两类:普通广播和有序广播。
普通广播:通过Context.sendBroadcast()方法来发送,它是完全异步的。
所有的receivers的执行顺序不确定,因此所有的receivers接收broadcast的顺序不确定。
这种方式效率更高,但是BroadcastReceiver无法使用setResult系列、getResult系列及abort(中止)系列API
 
有序广播:是通过Context.sendOrderedBroadcast来发送,所有的receiver依次执行。
BroadcastReceiver可以使用setResult系列函数结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以abort系列函数来让系统丢弃该广播,使用该广播不再传送到别的BroadcastReceiver。
可以通过在intent-filter中设置android:priority属性来设置receiver的优先级,优先级相同的receiver其执行顺序不确定。
如果BroadcastReceiver是代码中注册的话,且其intent-filter拥有相同android:priority属性的话,先注册的将先收到广播。

有序广播,即从优先级别最高的广播接收器开始接收,接收完了如果没有丢弃,就下传给下一个次高优先级别的广播接收器进行处理,依次类推,直到最后。如果多个应用程序设置的优先级别相同,则谁先注册的广播,谁就可以优先接收到广播。

关于广播的定义,分为两种,动态注册和静态注册。

动态注册的广播接收器永远要快于静态注册的广播接收器,不管静态注册的广播接收器的优先级是否高于动态注册的广播接收器的优先级。

动态注册的广播不是常驻型的,他是跟随着activity的生命周期的。一般在开发中都会在onDestroy()方法中移除广播。静态注册的广播是常驻型的广播,也就是说当应用程序关闭的时候,如果有信息广播来,程序也会被系统调用。在同一优先级下,谁启动的快,谁将先收到广播。

http://drops.wooyun.org/tips/4393
有些广播只能通过动态方式注册,比如时间变化事件、屏幕亮灭事件、电量变更事件,因为这些事件触发频率通常很高,如果允许后台监听,会导致进程频繁创建和销毁,从而影响系统整体性能。


参考资料:


### 广播机制概述 Android广播是一种系统级的消息传递机制,用于在应用程序之间或系统与应用程序之间发送和接收事件通知。通过广播,应用可以监听并响应特定的系统事件(如设备启动完成、电池电量低等)或其他应用发出的自定义事件。 广播分为两种类型:**有序广播**和**粘滞广播**。有序广播允许接收者按照优先级顺序依次处理广播消息,而粘滞广播则是在广播发送后注册的接收者仍然能够接收到该广播。 #### 注册广播接收器 广播接收器可以通过两种方式注册:静态注册和动态注册。 - **静态注册**:在`AndroidManifest.xml`文件中声明广播接收器。这种方式适用于需要长期运行的广播接收器,即使应用未启动也能接收到广播。 ```xml <receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="com.example.MY_ACTION" /> </intent-filter> </receiver> ``` - **动态注册**:在代码中使用`registerReceiver()`方法注册广播接收器。这种方式适用于需要在特定条件下才启用的广播接收器,且在不再需要时应调用`unregisterReceiver()`方法注销。 ```java IntentFilter filter = new IntentFilter("com.example.MY_ACTION"); registerReceiver(myBroadcastReceiver, filter); ``` #### 发送广播 发送广播可以通过`sendBroadcast()`方法实现,传入一个`Intent`对象指定广播的动作和其他数据。 ```java Intent intent = new Intent("com.example.MY_ACTION"); intent.putExtra("data", "Hello World"); sendBroadcast(intent); ``` 对于有序广播,可以使用`sendOrderedBroadcast()`方法,并指定一个权限字符串来限制哪些应用可以接收此广播。 ```java sendOrderedBroadcast(intent, null); ``` ### 使用场景示例 #### 系统广播 系统广播Android系统自动发出的广播,例如当设备启动完成后会发出`ACTION_BOOT_COMPLETED`广播。开发者可以在应用中注册这些广播以执行相应的操作。 ```xml <receiver android:name=".BootCompletedReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> ``` #### 自定义广播 除了系统广播外,开发者还可以创建自己的广播,以便在应用内部或不同应用间传递信息。 ```java Intent intent = new Intent("com.example.CUSTOM_ACTION"); intent.putExtra("message", "This is a custom broadcast"); sendBroadcast(intent); ``` ### 注意事项 - **权限管理**:发送或接收某些广播可能需要特定的权限。在`AndroidManifest.xml`中声明所需的权限,或者在运行时请求权限。 ```xml <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> ``` - **性能优化**:避免在广播接收器中执行耗时的操作,因为这可能会导致主线程阻塞。如果需要执行长时间任务,建议启动一个服务或使用异步任务。 - **安全性**:确保广播的安全性,防止恶意应用滥用。可以通过设置权限或使用本地广播(LocalBroadcastManager)来限制广播的作用范围。 ### 示例代码 以下是一个简单的广播接收器实现,用于接收并处理自定义广播: ```java public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if ("com.example.CUSTOM_ACTION".equals(action)) { String message = intent.getStringExtra("message"); Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } } } ``` 在活动中注册和注销广播接收器: ```java private MyBroadcastReceiver myBroadcastReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myBroadcastReceiver = new MyBroadcastReceiver(); IntentFilter filter = new IntentFilter("com.example.CUSTOM_ACTION"); registerReceiver(myBroadcastReceiver, filter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(myBroadcastReceiver); } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值