一前同事开发的一检测工具,手机需要通过网络与 PC 进行通信,之前一直用着很好,今天在一 Android 7.0 手机上进行使用的时候,每次必崩。崩溃日志显示 android.os.NetworkOnMainThreadException,查看崩溃处的代码,原来该处的 DataOutputStream.write() 放在了主线程中,因为 Android 在 2.3 之后就不允许在主线程中访问网络数据,否则会抛出 android.os.NetworkOnMainThreadException,所以才会崩溃,但是转念一想,之前使用过的其他4.X、5.X、6.X 的手机为什么没有抛此异常?后来在StackOverflow 上找到了答案:
Due to a bug in previous versions of Android, the system did not flag writing to a TCP socket on the main thread as a strict-mode violation. Android 7.0 fixes this bug. Apps that exhibit this behavior now throw an android.os.NetworkOnMainThreadException. Generally, performing network operations on the main thread is a bad idea because these operations usually have a high latency that causes ANRs and jank.
原来这是 Android 的一 Bug, 7.0 之前的 Android 版本未能将对主线程上的 TCP 套接字的写入操作举报为严格模式违反, 7.0(Android N) 修复了此错误。如果应用仍在主线程执行 TCP 套接字的写入操作会引发 android.os.NetworkOnMainThreadException。
一般情况下,我们不建议在主线程上执行网络操作,因为这些操作通常都有可能导致 ANR 和卡顿的高尾延迟。