StrictMode java.lang.Throwable: обнаружен сокет без тегов

С включенным StrictMode я только начал получать это исключение:

java.lang.Throwable: обнаружен сокет без тегов; используйте TrafficStats.setThreadSocketTag() для отслеживания всего использования сети


person Jose Gómez    schedule 09.12.2017    source источник
comment
Здесь есть немного официального документа по этому поводу: source.android.com/devices/ tech/datausage/tags-explained   -  person Sam    schedule 15.11.2020


Ответы (2)


Есть несколько способов обработки этого исключения. Во-первых, вы должны проверить трассировку стека и убедиться, что это ваш код сообщает о нарушении. Например, взгляните на следующую трассировку.

D/StrictMode: StrictMode policy violation: android.os.strictmode.UntaggedSocketViolation: Untagged socket detected; use TrafficStats.setThreadSocketTag() to track all network usage
    at android.os.StrictMode.onUntaggedSocket(StrictMode.java:2124)
    at com.android.server.NetworkManagementSocketTagger.tag(NetworkManagementSocketTagger.java:82)
    at libcore.io.BlockGuardOs.tagSocket(BlockGuardOs.java:52)
    at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:372)
    at libcore.io.ForwardingOs.socket(ForwardingOs.java:217)
    at libcore.io.IoBridge.socket(IoBridge.java:658)
    at java.net.PlainSocketImpl.socketCreate(PlainSocketImpl.java:128)
    at java.net.AbstractPlainSocketImpl.create(AbstractPlainSocketImpl.java:128)
    at java.net.ServerSocket.createImpl(ServerSocket.java:306)
    at java.net.ServerSocket.getImpl(ServerSocket.java:259)
    at java.net.ServerSocket.bind(ServerSocket.java:377)
    at java.net.ServerSocket.<init>(ServerSocket.java:237)
    at java.net.ServerSocket.<init>(ServerSocket.java:128)
    at com.java42.android03.binder.peer.messaging.J42PM_ServerConnection.run(J42PM_ServerConnection.java:52)
    at com.java42.base.components.utility.impl.Utility_Thread$1.run(Utility_Thread.java:137)
    at java.lang.Thread.run(Thread.java:919)
    at com.java42.utility.base.J42Thread.run(J42Thread.java:38)

Вызов приложения, который является нарушением:

J42PM_ServerConnection.run(J42PM_ServerConnection.java:52)

Далее взгляните на этот код:

public void run() {
    try (ServerSocket serverSocket = new ServerSocket(port)) {
        this.serverSocket = serverSocket;
        CallerId.identifyBasic("J42PSC0179D: listening Inbound....");
        while (!Thread.currentThread().isInterrupted()) {
        ...

Поскольку это цикл на стороне сервера, а идентификатор потока не меняется в течение всего срока службы серверного процесса, вы можете исправить нарушение, добавив вызов TrafficStats.setThreadStatsTag() с использованием текущего идентификатора потока.

public void run() {
    TrafficStats.setThreadStatsTag((int) Thread.currentThread().getId()); // <---
    try (ServerSocket serverSocket = new ServerSocket(port)) {
        this.serverSocket = serverSocket;
        CallerId.identifyBasic("J42PSC0179D: listening Inbound....");
        while (!Thread.currentThread().isInterrupted()) {
        ...

Давайте посмотрим на другую трассировку:

D/StrictMode: StrictMode policy violation: android.os.strictmode.UntaggedSocketViolation: Untagged socket detected; use TrafficStats.setThreadSocketTag() to track all network usage
    at android.os.StrictMode.onUntaggedSocket(StrictMode.java:2124)
    at com.android.server.NetworkManagementSocketTagger.tag(NetworkManagementSocketTagger.java:82)
    at libcore.io.BlockGuardOs.tagSocket(BlockGuardOs.java:52)
    at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:372)
    at libcore.io.ForwardingOs.socket(ForwardingOs.java:217)
    at libcore.io.IoBridge.socket(IoBridge.java:658)
    at java.net.PlainSocketImpl.socketCreate(PlainSocketImpl.java:128)
    at java.net.AbstractPlainSocketImpl.create(AbstractPlainSocketImpl.java:128)
    at java.net.Socket.createImpl(Socket.java:489)
    at java.net.Socket.<init>(Socket.java:446)
    at java.net.Socket.<init>(Socket.java:218)
    at com.java42.android03.binder.peer.messaging.J42PM_ClientConnection.run(J42PM_ClientConnection.java:54)
    at com.java42.android03.binder.peer.messaging.J42PM_Client$2.run(J42PM_Client.java:86)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:919)

Как и в первом примере, вы определяете вызов приложения, который нарушает правила:

J42PM_ClientConnection.run(J42PM_ClientConnection.java:54)

Далее взгляните на этот код:

InetSocketAddress socketAddress = serviceResolver.getSocketAddress();
    connection = new J42PM_ClientConnection(socketAddress, responseHandler);
    executorService.execute(new Runnable() {
        @Override
        public void run() {
        connection.run();
        ...

Обратите внимание, что этот код использует службу-исполнитель для запуска соединения на стороне клиента. Идентификатор потока будет меняться в течение жизни процесса по мере создания и уничтожения соединений. Я не уверен, что это исказит отчеты о трафике, но я думаю, что лучше всего отслеживать использование на этом этапе, используя постоянное значение. Выберите какой-нибудь уникальный номер. Использование номера строки файла является простым выбором.

    InetSocketAddress socketAddress = serviceResolver.getSocketAddress();
    connection = new J42PM_ClientConnection(socketAddress, responseHandler);
    executorService.execute(new Runnable() {
        @Override
        public void run() {
        TrafficStats.setThreadStatsTag(42); // <--
        connection.run();
        ...

И последний комментарий: если вы не видите вызов своего кода в трассировке стека, вы мало что можете сделать, чтобы остановить нарушение. Проблема в другой библиотеке, и если вы не можете связаться с владельцем библиотеки, просто игнорируйте нарушение.

person Java42    schedule 16.09.2019

Мое решение состояло в том, чтобы вызвать инициализацию следующим образом:

private static final int THREAD_ID = 10000;
TrafficStats.setThreadStatsTag(THREAD_ID);
person Jose Gómez    schedule 09.12.2017
comment
Где ты это назвал? - person Ralf; 05.03.2018
comment
Вы должны вызвать это в потоке, который осуществляет связь, но это не всегда полностью понятно для меня. Если кто-то может добавить дополнительную информацию об этом, это будет здорово. - person Jose Gómez; 04.04.2018