Broadcast Receiver 广播机制

xiaoxiao2021-02-28  102

1、什么是安卓的Broadcast? 安卓的四大组件之一,是一种广泛应用在应用程序之间传输信息的机制。

2、什么是安卓的BroadcastReceiver? 是对发送出来的广播进行过滤接收并响应的一类组件,它就是用来接收来自系统和应用中的广播。例如系统的广播有开机广播: 系统在开机时候会发送开机广播,程序接收到之后,能进行开机自启动。 网络状态改变广播: 3g变wifi、网络断开等。电量改变广播等等。。。 (1).同一app内部的同一组件内的消息通信(单个或多个线程之间); (2).同一app内部的不同组件之间的消息通信(单个进程); (3).同一app具有多个进程的不同组件之间的消息通信; (4).不同app之间的组件之间消息通信; (5).Android系统在特定情况下与App之间的消息通信。

3、Anroid为什么要这样设计? 大大减少开发工作量和开发周期。作为开发者,只需要掌握BroadcastReceiver

4、怎么理解Broadcast和BroadcastReceiver ? Broadcast就像现实中的广播电台,他发广播信号来,然后我们用收音机来接收,然后处理,并且播放出声音, BroadcastReceiver就相当于那台收音机。

5、使用方法 发送: 把信息装入一个Intent对象(如:Action、Category),通过调相应的方法将Intent对象以广播的方式发送出去: sendBroadcast(); sendOrederBroadcast(); sendStickyBroadcast(); 接收: 当Intent发送之后,所有已经注册vedBroadcastReceiver会检查注册时的IntentFilter是否与发送的Intent相匹配,若匹配则就会调用BroadcastReceiver的onReceiver()方法。所以当我们定义一个BroadcastReceiver的时候,都需要实现onReceiver()方法。 注意: BroadcastReceiver需要注册 静态注册 代码动态注册

6、注意! BroadReceiver生命周期只有十秒左右,不能直接执行耗时操作,不然会出现ANR(应用程序无响应),也不能用子线程来做,因为每次广播来的时候都会创建一个Reveiver对象,并且调用onReceiver,执行完之后 ,对象会立刻被销毁,子线程也没了 要做耗时操作的话,应该通过发送Intent给Service,由Service来完成。 动态注册广播接受者的话要在Destory回调事件进行unregister

7、广播的分类 普通广播 (Normal broadcast) - 所有监听该广播接受者都可以监听到该广播 - 同级别接收先后顺序是随机的(无序) - 级别低的后收到广播 - 接收器不能截断广播的继续传播,也不能处理广播 - 同级别动态注册高于静态注册

有序广播 (Oredered broadcast) - 按照接收者的优先顺序来接收广播,优先级别在intent-filter中的priority中声明,-1000到1000之间,值越大优先级越高,可以终止广播的继续传播,接受者可以修改intent的内容。 - 同级别接收顺序是随机的 - 级别低的后收到 - 能截断广播的继续传播,高级别的广播接收器接收广播后能决定时候截断。 - 能处理广播 - 同级别动态注册高于静态注册

异步广播 (粘滞性滞留广播) ps:已被弃用 - 不能处理结果给下一个接收者,无法终止广播。 - 一直存在 - 可以先发送广播,再注册接收器 - 需要在清单文件添加android.permission.BROADCAST_STICKY权限





动态注册(在代码中注册广播接收器)

registerReceiver(networkChangeReceiver,intentFilter);

实例

MainActivity.class:

public class MainActivity extends AppCompatActivity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intentFilter = new IntentFilter(); //当网络发生变化时,系统发出的值就是 android.net.conn.CONNECTIVITY_CHANGE,也就是说我们的 //广播接收器想要监听什么广播 intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); //实例化一个广播接收器 networkChangeReceiver = new NetworkChangeReceiver(); //注册广播 第一个参数是我们要处理广播的广播接收器,第二个参数是意图过滤器 registerReceiver(networkChangeReceiver,intentFilter); } @Override protected void onDestroy() { super.onDestroy(); //取消注册 unregisterReceiver(networkChangeReceiver); } //一个广播接收器 class NetworkChangeReceiver extends BroadcastReceiver{ //每当网络状态发生变化时,onReceive()方法就会得到执行 @Override public void onReceive(Context context, Intent intent) { //网络连接服务类 ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); //获得网络连接实例 NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if(networkInfo!=null&&networkInfo.isAvailable()){ Toast.makeText(context,"network is available",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show(); } } } }





静态注册(在AndroidManifest.xml中注册广播接受器)

<receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>

enabled:表示是否启用这个播放器 exported:用于指示该服务是否能够被其他应用程序组件调用或跟它交互。

实例

MainActivity.class:

public class MainActivity extends AppCompatActivity { public static TextView textMessage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textMessage = (TextView) findViewById(R.id.message); } }

MyBroadcastReceiver.class:

public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"收到一条短信",Toast.LENGTH_SHORT).show(); StringBuilder builder = new StringBuilder(); //pdus是一个object类型的数组,每一个object都是一个byte[]字节数组,每一项为一条短信。 Object[] pduses= (Object[])intent.getExtras().get("pdus"); for(Object pdus: pduses){ byte[] pdusmessage = (byte[])pdus; SmsMessage sms = SmsMessage.createFromPdu(pdusmessage); String mobile = sms.getOriginatingAddress();//发送短信的手机号码 String content = sms.getMessageBody(); //短信内容 Date date = new Date(sms.getTimestampMillis()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time = format.format(date); //得到发送时间 builder.append("号码: "+mobile+"\n内容: "+content+"\n时间: "+time+"\n"); } MainActivity.textMessage.setText(builder.toString()); } }

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ukulele.broadcasttest"> <uses-permission android:name="android.permission.RECEIVE_SMS" /><!--接收短信权限--> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver> </application> </manifest>





Normal Broadcast 普通广播

sendBroadcast(intent);//发送广播

实例:

MainActivity.class:

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = (Button) findViewById(R.id.seond_broadcast); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent("com.example.broadcasttest.My_NORMAL_BROADCAST"); intent.putExtra("msg","普通广播"); sendBroadcast(intent); } }); } }

MyNormalBroadcast.class:

public class MyNormalBroadcast extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d("MyNormalBroadcast ",intent.getStringExtra("msg")); } }

AndroidManifest.xml:

<receiver android:name=".MyNormalBroadcast" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.example.broadcasttest.My_NORMAL_BROADCAST"/> </intent-filter> </receiver>

intent-filter android:priority=”1000” 普通广播也可设置先后顺序

logcat:

MyNormalBroadcast : 普通广播



Oredered Broadcast 有序广播

sendOrderedBroadcast(intent, null);//发送广播

有序广播实例:

MainActivity.class:

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = (Button) findViewById(R.id.seond_broadcast); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent("com.example.broadcasttest.My_OREDERED_BROADCAST"); intent.putExtra("name","总统"); intent.putExtra("content","快去把事情办了"); sendOrderedBroadcast(intent,null); } }); } }

MyOrederedBroadcast3.class:

public class MyOrederedBroadcast3 extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String name = intent.getStringExtra("name"); String content = intent.getStringExtra("content"); Log.d("MyOrederedBroadcast3","省长收到了"+name+"发过来的消息,消息内容是"+content); Bundle bundle = new Bundle(); bundle.putString("name","省长"); bundle.putString("content","快去把事情办了"); setResultExtras(bundle); //abortBroadcast(); 截断广播 } }

MyOrederedBroadcast2.class:

public class MyOrederedBroadcast2 extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //true代表如果前面的接收器没有存放数据,则自动创建一个空的Bundle对象,false则表示如果前面的接收器如果没有存放任何数据则返回null。 Bundle bundle = getResultExtras(true); String name = bundle.getString("name"); String content = bundle.getString("content"); Log.d("MyOrederedBroadcast2","市长收到了"+name+"发来的消息,消息内容是"+content); bundle.putString("name","市长"); bundle.putString("content","快去把事情办了"); setResultExtras(bundle); //abortBroadcast(); 截断广播 } }

MyOrederedBroadcast.class:

public class MyOrederedBroadcast extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = getResultExtras(true); String name = bundle.getString("name"); String content = bundle.getString("content"); Log.d("MyOrederedBroadcast","县长收到了"+name+"发来的消息,消息内容是"+content+ "。县长说:“好的市长,我这就去办”。"); } }

AndroidManifest.xml:

<receiver android:name=".MyOrederedBroadcast" android:enabled="true" android:exported="true" > <intent-filter android:priority="100"> <action android:name="com.example.broadcasttest.My_OREDERED_BROADCAST"/> </intent-filter> </receiver> <receiver android:name=".MyOrederedBroadcast2" android:enabled="true" android:exported="true" > <intent-filter android:priority="200"> <action android:name="com.example.broadcasttest.My_OREDERED_BROADCAST"/> </intent-filter> </receiver> <receiver android:name=".MyOrederedBroadcast3" android:enabled="true" android:exported="true"> <intent-filter android:priority="300"> <action android:name="com.example.broadcasttest.My_OREDERED_BROADCAST"/> </intent-filter> </receiver> <!--优先级的设定 MyReceiver3大于MyReceiver2,MyReceiver2大于MyReceiver,优先级的范围-1000~1000 -->

logcat:

MyOrederedBroadcast3: 省长收到了总统发过来的消息,消息内容是快去把事情办了 MyOrederedBroadcast2: 市长收到了省长发来的消息,消息内容是快去把事情办了 MyOrederedBroadcast: 县长收到了市长发来的消息,消息内容是快去把事情办了。县长说:“好的市长,我这就去办”。



Sticky Broadcast粘性广播

实例

MainActivity.class:

public class MainActivity extends AppCompatActivity { private MyStickyBroadcast myStickyBroadcast; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = (Button) findViewById(R.id.seond_broadcast); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent("com.example.broadcasttest.My_STICKY_BROADCAST"); intent.putExtra("msg","粘性广播"); //先发送 sendStickyBroadcast(intent); //后注册 IntentFilter intentFilter = new IntentFilter("com.example.broadcasttest.My_STICKY_BROADCAST"); myStickyBroadcast = new MyStickyBroadcast(); registerReceiver(myStickyBroadcast,intentFilter); } }); } @Override protected void onDestroy() { super.onDestroy(); //取消注册 unregisterReceiver(myStickyBroadcast); } class MyStickyBroadcast extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Log.d("MyStickyBroadcast",intent.getStringExtra("msg")); } } }

logcat:

MyStickyBroadcast: 粘性广播

AndroidManifest.xml:

<!--异步广播必须添加一条权限--> <uses-permission android:name="android.permission.BROADCAST_STICKY"/>



本地广播 前面我们发出的全局广播可以被其他应用程序接收到,同样我们也可以接受来自于其他应用程序的广播。这样就容易引起安全问题,比如我们发出的关键性数据可能被其他应用程序截获,或者接收到其他应用程序向我们发送的各种垃圾广播。 为了解决广播的安全问题,Android引用了一套本地广播机制,使用这套机制发出的广播只能够在应用程序的内部进行传递。

实例

MainActivity.class:

public class MainActivity extends AppCompatActivity { private LocalReceiver localReceiver; private LocalBroadcastManager localBroadcastManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //本地广播管理器 localBroadcastManager = LocalBroadcastManager.getInstance(this); IntentFilter intentFilter = new IntentFilter("com.example.broadcasttest.My_LOCAL_RECEIVER"); localReceiver = new LocalReceiver(); //使用本地广播管理器对广播接收器进行注册 localBroadcastManager.registerReceiver(localReceiver,intentFilter); Button button = (Button) findViewById(R.id.seond_broadcast); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent("com.example.broadcasttest.My_LOCAL_RECEIVER"); intent.putExtra("msg","本地广播"); localBroadcastManager.sendBroadcast(intent); } }); } @Override protected void onDestroy() { super.onDestroy(); localBroadcastManager.unregisterReceiver(localReceiver); } //本地广播接收器 class LocalReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Log.d("LocalReceiver",intent.getStringExtra("msg")); } } }
转载请注明原文地址: https://www.6miu.com/read-61167.html

最新回复(0)