With StrictMode enabled I just started getting this exception:
java.lang.Throwable: Untagged socket detected; use TrafficStats.setThreadSocketTag() to tra
There are a couple of ways to handle this exception. First, you have to inspect the stack trace and make sure it is your code reporting the violation. For example, have a look at the following trace.
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)
The app call that is in violation is:
J42PM_ServerConnection.run(J42PM_ServerConnection.java:52)
Next, have a look at that code:
public void run() {
try (ServerSocket serverSocket = new ServerSocket(port)) {
this.serverSocket = serverSocket;
CallerId.identifyBasic("J42PSC0179D: listening Inbound....");
while (!Thread.currentThread().isInterrupted()) {
...
Since this is the server-side loop, and the thread ID does not change for the life of server process, you can fix the violation by adding a call to TrafficStats.setThreadStatsTag() using the current thread id.
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()) {
...
Let's have a look at another trace:
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)
As in the first example, you identify the app call that is in violation:
J42PM_ClientConnection.run(J42PM_ClientConnection.java:54)
Next, have a look at that code:
InetSocketAddress socketAddress = serviceResolver.getSocketAddress();
connection = new J42PM_ClientConnection(socketAddress, responseHandler);
executorService.execute(new Runnable() {
@Override
public void run() {
connection.run();
...
Notice this code uses an executor service to run the client-side connection. The thread ID will change during the life of the process as connections are created and destroyed. I'm not certain if this will skew traffic reports but I think it best to track usage at this point using a constant value. Pick some unique number. Using the line number of the file is an easy choice.
InetSocketAddress socketAddress = serviceResolver.getSocketAddress();
connection = new J42PM_ClientConnection(socketAddress, responseHandler);
executorService.execute(new Runnable() {
@Override
public void run() {
TrafficStats.setThreadStatsTag(42); // <--
connection.run();
...
One last comment, if you don't see a call to your code in the stack trace, there is not much you can do to stop the violation. The problem is in another library and unless you can contact the library owner, simply ignore the violation.
My solution has been to call on initialisation the following:
private static final int THREAD_ID = 10000;
TrafficStats.setThreadStatsTag(THREAD_ID);
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork() // or .detectAll() for all detectable problems
.detectAll() // .penaltyDeath()
.penaltyLog()
.build()
)
StrictMode.setVmPolicy(
VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
.detectLeakedClosableObjects()
.detectAll()
.penaltyLog() // .penaltyDeath()
.build()
)
}