揭开Android非受保护广播异常的奥秘:深入解析和解决方案
2023-12-31 00:17:13
在Android开发中,非受保护广播异常是一个令人头疼的问题。它会悄然出现在log日志中,但实际上却对三方应用接收广播没有任何影响。然而,过多的此类异常提示可能会导致ANR问题和wtf文件的log覆盖,从而带来隐患。
本文旨在深入解析非受保护广播异常,并探索其解决方案。通过剖析Android框架源码,我们将揭示异常背后的根源,并提出切实可行的应对措施。
非受保护广播异常的本质
非受保护广播异常发生在三方应用接收非受保护广播(non-protected broadcast)时。所谓非受保护广播,是指没有指定接收者权限的广播。当三方应用尝试接收此类广播时,就会触发异常。
Android框架中,有一个名为ReceiverRestrictedContext的类负责广播的权限检查。如果接收广播的应用没有声明必要的权限,ReceiverRestrictedContext就会抛出异常。异常信息通常如下:
android.content.ReceiverCallNotAllowedException: Broadcast from 'package_name' (pid=1355) is not allowed for 10270 (uid=10070)
异常影响及危害
虽然非受保护广播异常本身不会影响三方应用接收广播,但过多的异常提示却会带来如下危害:
- 占用wtf日志文件空间,可能导致其他重要log被覆盖
- 可能触发ANR,影响应用稳定性
解决方案
解决非受保护广播异常的根本方法是:
- 确保三方应用声明必要的权限。 接收非受保护广播的应用必须在Manifest文件中声明相应的权限。
- 使用受保护广播代替非受保护广播。 如果可能,建议使用受保护广播(Protected Broadcast)。受保护广播要求接收者拥有特定的权限,可以有效防止异常的发生。
此外,还可以采取以下措施来减少异常提示:
- 检查应用程序中的非受保护广播。 使用代码分析工具或手动检查代码,找出所有使用非受保护广播的地方。
- 添加权限检查。 在接收非受保护广播之前,添加权限检查代码。如果应用没有必要的权限,则直接返回。
源码解析
为了深入理解非受保护广播异常的根源,我们对Android框架源码进行了解析。具体代码位于:
frameworks/base/core/java/android/content/ReceiverRestrictedContext.java
ReceiverRestrictedContext类中有一个方法名为checkReceiverRestrictedContext,负责检查接收广播的权限。如果接收者没有声明必要的权限,就会抛出异常。
public static void checkReceiverRestrictedContext(int callingUid, Context context) {
if (!isReceiverRestrictedContext(context)) {
return;
}
String msg = "Broadcast from '" + context.getOpPackageName() + "' (pid=" + callingUid + ") is not allowed for " + context.getUserId() + " (uid=" + context.getUserId() + ")";
throw new ReceiverCallNotAllowedException(msg);
}
结论
非受保护广播异常是一个常见的Android开发问题。通过理解其根源并采取适当的解决方案,我们可以有效防止异常的发生,避免其对应用稳定性的影响。本文深入解析了异常的本质、影响和解决方案,并基于源码分析提供了切实可行的应对措施。希望本文能帮助Android开发者解决非受保护广播异常问题,提升应用质量。