Android四大组件-BroadcastReceiver
来源:互联网 发布:自己淘宝店铺的二维码 编辑:程序博客网 时间:2024/05/16 19:30
广播:BoradcastReceiver
1 、BoradcastReceiver的作用?
Broadcast receiver 是一个用来响应系统范围内的广播的组件。 很多广播发自于系统本身。—例如, 通知屏幕已经被关闭、电池低电量、照片被拍下的广播。 应用程序也可以发起广播。—例如, 通知其它程序,一些数据被下载到了设备,且可供它们使用。 虽然广播并不提供用户交互界面,它们也可以创建一个状态栏通知 来提醒用户一个广播事件发生了。尽管如此,更多的情形是,一个广播只是进入其它组件的一个“门路”,并试图做一些少量的工作。 例如,它可能发起一个服务,并通过服务执行与这个广播事件相关的工作。
数据传输与共享,比如系统自带广播,开机广播,电量广播,短信,电话广播等。
起到通知的作用,比如在收到广播后,开启Service,启动Activity,或者进入网络查询或者更新Ui界面;
在android中比较常用的情景是Activity与startService()方法的启动通过BroadcastReceiver()来实现
2、生命周期
developer上的描述:
翻译:
广播生命周期
一个BroadcastReceiver对象仅适用执行在onReceive的时间上(上下文,意图)。一旦你的代码返回这个函数,系统考虑的对象将完成,不再活跃。
这具有重要的影响,你可以做什么在onReceive(上下文,意图)执行:任何需要异步操作是不可用的,因为你需要从函数中返回处理异步操作,但在这一点上,BroadcastReceiver不再活跃,因此系统在执行异步操作前已经将它杀死。
特别是,你可能不会显示一个对话框或绑定到一个服务从一个BroadcastReceiver中。对于前者,你应该使用NotificationManager API。对于后者,你可以使用上下文。startservice()将命令发送到服务。
3、 广播中为什么不能做耗时操作,或者开子线程进行耗时操作?
在广播中当调用了onReciver()方法并传递它包含消息的intent对象,广播接收者认为当它执行这个方法的时候为活跃的,当onReceive()执行后,它是不活跃的。活跃的广播接收者进程是受保护的,不会被杀死, 但系统可以在任何时候杀死不活跃的进程,特别是内存吃紧的时候。如果在广播中作耗时操作,并且onReceive()方法执行后,开的子线程没有执行完,有可能广播已经被销毁了,并且每次发送的广播都会创建BroadcastReceiver的实例。因此, BroadcastReceiver中不能作耗时操作,如果超过10秒中就是报ANR异常;
如果要做耗时操作的话,应该在广播中用intent开启一个Service,在服务中开启线程,做耗时操作;
4、两种开启广播的方式:
1、静态注册,在清单文件中注册,这种广播开启的方式比较常用。即使应用退出了,广播也能接收到消息。
2、动态注册(与Service的bindService相似): 就是在代码中注册,不用在清单文件中注册但这注册方式启动的广播,要在组件销毁的时候,解除注册,如果不解除退出程序可能报错。
5、有序广播和无序广播
developer描述:
翻译:
普通广播(Context.sendBroadcast)是完全异步的。广播的所有接收器都运行在未定义的顺序中,通常在同一时间。这是更有效的,但这意味着接收器不能使用的结果在广播中中止。
有序广播(Context.sendorderedbroadcast)被传递到一个接收器中。由每个接收端执行,它可以向下一个接收器传递一个广播,或者它可以完全中止广播,以便它不会被传递给其他接收器。在可与安卓控制的顺序接收器中,匹配的意图过滤器的优先级属性,与相同优先级的接收器将在任意顺序运行。
普通广播:通过sendBroadcast()方法来发送。通过这种形式发送广播接收的顺序也是不确定的。但效率比较高
有序广播:是通过sendOrderedBroadcast来发送。按优先级的不同,优先Receiver可对数据进行处理,并传给下一个Receiver效率比较低。可以在清单文件中设置优先级从-1000-1000;
<intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>-->
终止广播:abrotBroadcast()
当android系统接收到短信时,会发送一个广播BroadcastReceiver(),这个广播是有序的形式发送的。
短信拦截器的功能就是把BroadcastReceiver的优先级设置的比较系统高,当收到这条广播时,终止广播。这样就可以拦截短信了
1、静态的方式创建广播,以接收到短信为例:
在xml文件中注册:
<receiver android:name=".MsgReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>
添加权限:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
在MsgReceiver()中的代码:
public class MsgReceiver extends BroadcastReceiver { private static final String TAG = "MsgReceiver"; @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); SmsMessage[] smsMessages = null; Object[] pdus = null; if (bundle != null) { pdus = (Object[]) bundle.get("pdus"); } if (pdus !=null){ smsMessages = new SmsMessage[pdus.length]; String sender = null; String content = null; for (int i=0; i<pdus.length; i++){ smsMessages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); sender = smsMessages[i].getOriginatingAddress(); content = smsMessages[i].getMessageBody(); Log.i(TAG, "SMS:"+sender+content); } } }}
在activity中什么也不做,发送短信给10086则:
从log中可以看到短信内容为:
2、通过动态的方式注册广播,也就是在代码中注册(这种方式的注册广播使用的比较少,因为它需要手机注销广播,如果没有注销广播,退出时发报异常)
在MyReceiver()中代码:
public class MyReceiver extends BroadcastReceiver { private static final String TAG="MyReceiver"; private String msg; @Override public void onReceive(Context context, Intent intent) { //在发送广播时的标识 if(intent.getAction().equals("a")){ msg=intent.getStringExtra("name"); }; Log.i(TAG, msg); }}
在MainActivity中的注册代码:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; public static final String TAG_ID=""; private Button btn_send; private MyReceiver receiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_send = (Button) findViewById(R.id.btn_send); btn_send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { receiver = new MyReceiver(); //意图过滤器,过滤Intent; IntentFilter filter = new IntentFilter(); filter.addAction("a"); //注册广播; registerReceiver(receiver, filter); //在Intent中携带数据,也可以用Bundle Intent intent =new Intent(); //发送广播时的设置的一个标识,用于标识是从哪里发过来。 intent.setAction("a"); //也可以能过Bundle打包传递数据; intent.putExtra("name", "csdn"); //发送广播 sendBroadcast(intent); Log.i(TAG, "发送广播"); } }); } @Override protected void onDestroy() { super.onDestroy(); //解除注册; if(receiver!=null) { unregisterReceiver(receiver); } }}
通过这种方式开启的广播在退出应用时,一定要注销广播。
- Android四大组件----BroadcastReceiver
- Android四大组件-BroadcastReceiver
- Android四大组件-BroadcastReceiver
- Android四大组件----BroadcastReceiver
- android四大组件---BroadCastReceiver
- Android四大组件:BroadcastReceiver
- Android四大组件:BroadcastReceiver
- Android四大组件:BroadcastReceiver
- (Android四大组件)---BroadcastReceiver
- android四大组件之BroadCastReceiver
- android 四大组件之 broadcastreceiver
- Android 四大组件之一 BroadcastReceiver
- android四大组件之BroadcastReceiver
- Android四大组件之BroadcastReceiver
- Android四大组件之BroadcastReceiver
- Android四大组件之BroadcastReceiver
- Android四大组件之BroadcastReceiver
- Android四大组件之一:BroadcastReceiver
- 最新版eclipse Mars 配置 maven
- checksum 軟體
- 【MyEclipse】配置代码格式化模版
- angularJS的路由ngRoute
- 欢迎使用CSDN-markdown编辑器
- Android四大组件-BroadcastReceiver
- Android中Canvas绘图基础详解
- js简单的设置快捷键,hotkeys捕获键盘键和组合键的输入
- 单例模式——C++模板实现
- (系统讲解)java内存分配分析/栈内存、堆内存
- 数据库模式对象
- 关于CBitmap的一点心得
- 在linux终端下打开pdf文件
- linux socket, serial编程