Android BroadcastReceiver传输机制详解
刘知意 人气:0Broadcast
应用程序之间传输信息的机制
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;
可以发送和接收分开,先发送再接收
发送完广播要卸载
加载全部内容