首页 > 解决方案 > Android OS 如何识别主线程上的网络调用并抛出 NetworkOnMainThreadException

问题描述

我正在尝试找到 AOSP 源代码的一部分,该部分负责保护在主线程上进行网络调用并NetworkOnMainThreadException因此引发异常,但到目前为止我失败了。

那么Android如何识别主线程上的网络调用呢?它是否检查操作系统的某些网络组件(可能发生在硬件层?)是否被触摸?

感谢Michael Dodd的回答,我找到了引发异常的位置(您可以通过此搜索找到它)。现在的问题是谁以及何时调用该android.os.StrictMode.onNetwork()方法。

标签: androidandroid-sourcenetworkonmainthread

解决方案


感谢 Michael Dodd 的回答,我发现它是如何工作的,例如对于 Android 8,有:

/**
 * Resolves a hostname to its IP addresses using a cache.
 *
 * @param host the hostname to resolve.
 * @param netId the network to perform resolution upon.
 * @return the IP addresses of the host.
 */
private static InetAddress[] lookupHostByName(String host, int netId)
        throws UnknownHostException {
  BlockGuard.getThreadPolicy().onNetwork();
  // ...
}

并且(感谢 Michael Dodd)在android.os.StrictMode中你可以找到:

// Part of BlockGuard.Policy interface:
public void onNetwork() {
    if ((mPolicyMask & DETECT_NETWORK) == 0) {
        return;
    }
    if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) {
        throw new NetworkOnMainThreadException();
    }
    if (tooManyViolationsThisLoop()) {
        return;
    }
    BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask);
    e.fillInStackTrace();
    startHandlingViolationException(e);
}

mPolicyMask设置来自android.app.ActivityThread.javaPENALTY_DEATH_ON_NETWORKvia :android.os.StrictMode.enableDeathOnNetwork()

/**
* For apps targetting Honeycomb or later, we don't allow network usage
* on the main event loop / UI thread. This is what ultimately throws
* {@link NetworkOnMainThreadException}.
*/
if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
    StrictMode.enableDeathOnNetwork();
}

推荐阅读