欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android之Broadcast总结篇

程序员文章站 2022-06-22 21:23:56
Android面试之Broadcast1.广播是什么、使用场景。 2 广播的种类。 3. 广播接收器。 4. 源码角度分析广播机制...

1.广播是什么

1.1 定义

在 Android 中,广播是一种广泛运用在应用程序之间 传输信息的机制,Android 中我们发送广播内容是一个 Intent ,这个 Intent 中可以携带我们要发送的数据。

1.2 广播的使用场景

  1. 同一app内有多个进程的不同组件之间的消息通信。
  2. 不同app之间的组件之间消息的通信。

2 广播的种类

2.1 无序广播

	//不可被拦截,当然发送的数据,接收者是不能进行修改的。	
	context.sendBroadcast(Intent); 

2.2 有序广播

发送出去的广播被广播接收者按照先后顺序接收,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,
优先级(priority)高的广播接收器会先收到广播消息。有序广播可以被接收器截断使得后面的接收器无法收到它;

	context.sendOrderBroadcast(Intent)	

可被拦截,而且接收者是可以修改其中要发送的数据,修改和添加都是可以的,这就意味着优先接收者对数据修改之后,下一个接收者接受的数据是上一个接收者已经修改了的,这必须明白。

2.3 本地广播

	localBroadcastManager.sendBroadcast(Intent);

只在app内传播。数据更加安全,效率更高,但 只能采用动态注册的方式

本地广播的发送和注册广播接收器都需要使用 LocalBroadcastManager 类,

	//本地广播的发送:
	public static void sendLocalBroadcast(Context context,String action){

		Intent intent = new Intent(action);
		LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
		localBroadcastManager.sendBroadcast(intent);

	}
	//本地广播的接收器的注册:
	IntentFilter intentFilter = new IntentFilter();
	LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);

	intentFilter.addAction(new BroadcastUtil().action_next);
	nasbr = new NextAndStartBroadcastReceiver();
	//注册本地广播接收器
	localBroadcastManager.registerReceiver(nasbr, intentFilter);

2.4 系统广播

普通广播:开发者自身定义 intent的广播(最常用),所有的广播接收器几乎会在同一时刻接受到此广播信息,接受的先后顺序随机

监听网络变化 android.net.conn.CONNECTIVITY_CHANGE
关闭或打开飞行模式 Intent.ACTION_AIRPLANE_MODE_CHANGED
充电时或电量发生变化 Intent.ACTION_BATTERY_CHANGED
电池电量低 Intent.ACTION_BATTERY_LOW
电池电量充足(即从电量低变化到饱满时会发出广播 Intent.ACTION_BATTERY_OKAY
系统启动完成后(仅广播一次) Intent.ACTION_BOOT_COMPLETED
按下照相时的拍照按键(硬件按键)时 Intent.ACTION_CAMERA_BUTTON
屏幕锁屏 Intent.ACTION_CLOSE_SYSTEM_DIALOGS
设备当前设置被改变时(界面语言、设备方向等) Intent.ACTION_CONFIGURATION_CHANGED
插入耳机时 Intent.ACTION_HEADSET_PLUG
未正确移除SD卡但已取出来时(正确移除方法:设置–SD卡和设备内存–卸载SD卡) Intent.ACTION_MEDIA_BAD_REMOVAL
插入外部储存装置(如SD卡) Intent.ACTION_MEDIA_CHECKING
成功安装APK Intent.ACTION_PACKAGE_ADDED
成功删除APK Intent.ACTION_PACKAGE_REMOVED
重启设备 Intent.ACTION_REBOOT
屏幕被关闭 Intent.ACTION_SCREEN_OFF
屏幕被打开 Intent.ACTION_SCREEN_ON
关闭系统时 Intent.ACTION_SHUTDOWN
重启设备 Intent.ACTION_REBOOT
……

2.5 粘性广播:

这种广播会一直滞留,当有匹配该广播的接收器被注册后,该接收器就会收到此条广播


3. 广播接收器

广播接收器是专门用来接收广播信息的,它可分为静态注册和动态注册:

3.1 静态注册

首先创建一个广播接收器类,实例代码如下:

public class BootCompleteReceiver extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {
		Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
	}
}

在 onReceive() 方法中对广播进行处理。

静态的广播接收器一定要在 AndroidManifest.xml 文件中注册,AndroidManifest.xml 文件中注册静态广播代码如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	package="com.example.broadcasttest"
	android:versionCode="1"
	android:versionName="1.0" >
	……
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

	<application
		android:allowBackup="true"
		android:icon="@drawable/ic_launcher"
		android:label="@string/app_name"
		android:theme="@style/AppTheme" >
		……
	
		<receiver
			android:name=".BootCompleteReceiver" >
			<intent-filter>
			<action android:name="android.intent.action.BOOT_COMPLETED" />
			</intent-filter>
		</receiver>
	</application>
</manifest>

所有静态的广播接收器都是在这里进行注册的。它的用法其实和标签非常相似,也是通过 android:name 来指定具体注册哪一个广播接收器,而 enabled 和 exported 属性则是创建 receiver 时自动生成的。

3.2 动态注册

如何创建一个广播接收器呢?新建一个类,让它继承自 BroadcastReceiver,并重写父类的 onReceive() 方法。

有广播到来时,onReceive() 方法就会得到执行,具体的逻辑就可以在这个方法中处理。来个简单的例子:监听网络变化,

其实就是新建一个广播接收器去接收来自系统网络变化的广播即可,代码如下所示:

public class MainActivity extends AppCompatActivity{

	private IntentFilter intentFilter;
	
	private NetWorkChangeReceiver netWorkChangeReceiver;
	
	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.Oncreata(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		intentFilter = new IntentFilter();
		intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
		networkChangeReceiver = new NetWorkChangeReceiver();
		registerReceiver(networkChangeReceiver, intentFilter);//注册广播接收器
	}
	
	@Overrid
	protected void onDestroy(){
		unregisterReceiver(networkChangeReceiver);//一定要记得取消广播接收器的注册
		super.onDestroy();
	}
	
	class NetworkChangeReceiver extends BroadcastReceiver{//广播接收器类
	
		@Override
		public void onReceiver(Context context,Intent intent){
		
			//这里需要权限,需要在AndroidManifest.xml中进行网络访问权限申请:
			//<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
			ConnectivityManager connectionManager = (ConnectivityManager)
			getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo networkInfo = connectionManager.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();
			}
		}
	}
}

动态注册广播接收器的优点以及缺点

  1. 动态注册的广播接收器可以*地控制注册与注销,在灵活性方面有很大优势,
  2. 缺点:即必须要在程序启动之后才能接收到广播,因为注册的逻辑是写在 onCreate() 方法中的。那么有没有广播能在程序未启动的情况下就能接收到广播呢?静态注册的广播接收器就可以做到。

4. 源码角度分析广播机制

4.1 系统广播的源码角度分析

  1. 自定义广播接收者 BroadcastReceiver ,并且重写 onReceiver() 方法。
  2. 通过 Binder 机制向 AMS(Activity Manager Service) 进行注册。
  3. 广播发送者通过 Binder 机制向 AMS 发送广播。
  4. AMS 查找符合条件 (IntentFilter/Permission等) 的 BroadcastReceiver,将广播发送到相应的 BroadcastReceiver (一般情况下是Activity)的消息队列中。
  5. 消息循环执行拿到此广播,回调 BroadcastReceiver 中的 onReceiver() 方法。

4.2 本地广播的源码角度分析

相比于系统广播而言,本地广播更加安全,更加高效,

以下是本地广播的特点以及内部的实现机制:
特点

  1. 使用它发送的广播将只在自身app内传播,不必担心泄漏隐私的数据。
  2. 其他app无法对你的app发送该广播,因此你的app根本不可能收到非自身app 发送的该广播,不必担心有安全漏洞可以利用。
  3. 比系统广播更加高效。

内部实现机制

  1. LocalBroadcast 高效 的原因:因为它内部是通过 Handler 实现的,它的 sendBroadcast() 方法含义并非和系统的sendBroadcast()一样,它的 sendBroadcast() 方法其实就是通过 Handler 发送了一个 Message 而已。

  2. LocalBroadcast 安全 的原因:既然它是通过Handler实现广播发送的,那么相比系统广播通过Binder机制实现那肯定更加高效,同时使用Handler来实现,别的app无法向我们应用发送该广播,而我们app内部发送的广播也不会离开我们的app。

    LocalBroadcast 内部协作主要是靠两个 Map 集合:mReceivers 和 mActions ,当然还有一个 List 集合 mPendingBroadcasts,这个主要存储待接收的广播对象。

4.3 广播发送和接收的原理 ?(Binder机制、AMS)

Android之Broadcast总结篇


声明:本文整理自网络,如有侵权请及时联系。

本文地址:https://blog.csdn.net/liusaisaiV1/article/details/107225699

相关标签: 面试准备