Search code examples
androidandroid-sourcenetworkonmainthread

How Android OS recognizes network calls on main thread and throws NetworkOnMainThreadException


I'm trying to find the part of AOSP's source code which is responsible for guarding for making network calls on main thread and throwing NetworkOnMainThreadException as a result but so far I failed.

So how Android recognizes network calls on main thread? Does it check if some network component (maybe it happens in HW layer?) of the OS was touched?

Thanks for Michael Dodd answer I found where the exception is thrown (you can find it by this search). Now the question is who and when calls the android.os.StrictMode.onNetwork() method.


Solution

  • Thanks for Michael Dodd answer I found how it works, e.g. for Android 8 there is:

    /**
     * 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();
      // ...
    }
    

    and (thanks to Michael Dodd) in android.os.StrictMode you can find:

    // 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);
    }
    

    The mPolicyMask sets the PENALTY_DEATH_ON_NETWORK via android.os.StrictMode.enableDeathOnNetwork() from android.app.ActivityThread.java:

    /**
    * 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();
    }