返回

揭开Android非受保护广播异常的奥秘:深入解析和解决方案

Android

在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开发者解决非受保护广播异常问题,提升应用质量。