Android BroadcastReceiver传输机制详解
作者:刘知意
Android开发的四大组件分别是:活动(activity),用于表现功能;服务(service),后台运行服务,不提供界面呈现;广播接受者(Broadcast Receive),勇于接收广播;内容提供者(Content Provider),支持多个应用中存储和读取数据,相当于数据库,本篇着重介绍广播组件
Broadcast
应用程序之间传输信息的机制
BroadcastReceiver
接收来自系统和应用中的广播
作用:在特定时间发送特定的标识,让程序进行操作
使用方法
注:
- BroadcastReceiver生命周期只有十秒左右
- BroadcastReceiver里不能做一些比较耗时的操作
- 应该通过Intent给Service,有Service完成
- 不能使用子线程
广播的种类
普通广播(Normal broadcasts)
所有监听该广播的广播接收者都可以监听到该广播
特点:
- 同级别接收先后是随机的
- 级别低的后收到广播
- 接收器不能截断广播的继续传播也不能处理广播
- 同级别动态注册高于静态注册
package com.example.broadcastsdemo; import androidx.appcompat.app.AppCompatActivity; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void doclick(View view) { switch (view.getId()){ case R.id.send1: //发送一条普通广播 Intent intent = new Intent(); intent.putExtra("msg","这是一条普通广播"); intent.setAction("BC_MSG"); intent.setComponent(new ComponentName("com.example.broadcastsdemo", "com.example.broadcastsdemo.BC1")); sendBroadcast(intent); Log.e("TAG", "doclick: 点击发送广播"); break; } } }
xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center|top" xmlns:android="http://schemas.android.com/apk/res/android"> <Button android:onClick="doclick" android:id="@+id/send1" android:text="发送一条普通广播" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
BC1
package com.example.broadcastsdemo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class BC1 extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = intent.getStringExtra("msg"); Log.e("TAG", "BC1接收到的广播信息 "+msg); } }
高版本需要用intent.setComponent指定接收者包路径和类路径
如果需要发给多个类广播,就使用intent.setPackage(“com.example.broadcastsdemo”);
同一包下的BroadcastReceiver都可以接收到广播
设置优先级
<receiver android:name=".BC1" android:enabled="true" android:exported="true"> <intent-filter android:priority="100"> <action android:name="BC_MSG"/> </intent-filter> </receiver> <receiver android:name=".BC2" android:enabled="true" android:exported="true"> <intent-filter android:priority="400"> <action android:name="BC_MSG"/> </intent-filter> </receiver>
只需要在intent-filter中设置android:priority就可以了
值-1000到1000越大优先级越高
截断广播
public class BC2 extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = intent.getStringExtra("msg"); Log.e("TAG", "BC2接收到的广播信息 "+msg); abortBroadcast(); } }
使用 abortBroadcast();关键字
发现普通广播无法中断广播的发送
静态注册是在xml中注册
动态注册
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); IntentFilter intentFilter = new IntentFilter("BC_MSG"); BC2 bc2 = new BC2(); registerReceiver(bc2,intentFilter); }
动态注册大于静态注册,但是他的作用域太低,容易死掉
测试BC1发广播BC2收
public class BC1 extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = intent.getStringExtra("msg"); Log.e("TAG", "BC1接收到的广播信息 "+msg); Bundle bundle = new Bundle(); bundle.putString("test","广播处理的数据BC1"); setResultExtras(bundle); } }
public class BC2 extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = intent.getStringExtra("msg"); Log.e("TAG", "BC2接收到的广播信息 "+msg); // abortBroadcast(); Bundle bundle = getResultExtras(true); String test = bundle.getString("test"); Log.e("TAG", "BC2得到的数据"+test ); } }
发现普通广播无法传送数据
有序广播(ordered broadcasts)
按照接收者的优先级顺序接收广播,优先级在intent-filter中的priority中声明。-1000到1000之间,值越大,优先级越高。可以终止广播意图的继续传播,接收者可以篡改内容
特点:
- 同级别接收顺序是随机的
- 能截断广播的继续传播,高级别的广播接收器收到该广播后,可以决定把该广播是否截断
- 接收器能截断广播的继续传播,也能处理广播
- 同级别动态注册高于静态注册
添加按钮
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center|top" xmlns:android="http://schemas.android.com/apk/res/android"> <Button android:onClick="doclick" android:id="@+id/send1" android:text="发送一条普通广播" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:onClick="doclick" android:id="@+id/send2" android:text="发送一条有序广播" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
添加事件处理
case R.id.send2: //发送一条普通广播 Intent intent2 = new Intent(); intent2.putExtra("msg","这是一条有序广播"); intent2.setAction("BC_MSG"); //intent.setComponent(new ComponentName("com.example.broadcastsdemo", "com.example.broadcastsdemo.BC1")); intent2.setPackage("com.example.broadcastsdemo"); sendOrderedBroadcast(intent2,null); Log.e("TAG", "doclick: 点击发送有序广播"); break;
发现有序广播可以实现BC2发消息给BC1,且可以中断广播
异步广播(粘滞性滞留广播)
不能将处理结果传给下一个接收者,无法终止广播
添加按钮及事件
<Button android:onClick="doclick" android:id="@+id/send3" android:text="发送一条异步广播" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
case R.id.send3: //发送一条异步广播 Intent intent3 = new Intent(); intent3.putExtra("msg","这是一条有序广播"); intent3.setAction("BC_MSG"); //intent3.setComponent(new ComponentName("com.example.broadcastsdemo", "com.example.broadcastsdemo.BC3")); intent3.setPackage("com.example.broadcastsdemo"); sendStickyBroadcast(intent3); IntentFilter intentFilter = new IntentFilter("BC_MSG"); BC3 bc3 = new BC3(); registerReceiver(bc3,intentFilter); break;
可以发送和接收分开,先发送再接收
发送完广播要卸载
到此这篇关于Android BroadcastReceiver传输机制详解的文章就介绍到这了,更多相关Android BroadcastReceiver 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!