启用了strictmode,我刚开始获得此例外:
java.lang.throwable:检测到未标记的插座;使用clabilstats.setthreadsockettag()跟踪所有网络使用
有几种处理此异常的方法。首先,您必须检查堆栈跟踪,并确保是您的代码报告违规行为。例如,请查看以下迹线。
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()) {
...
由于这是服务器端循环,并且线程ID不会在服务器过程的寿命上更改,因此您可以使用当前线程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()) {
...
让我们看一下另一个痕迹:
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();
...
请注意,此代码使用执行程序服务来运行客户端连接。随着连接的创建和破坏,线程ID将在过程的生命中发生变化。我不确定这是否会偏向流量报告,但我认为最好使用恒定值跟踪使用情况。选择一些唯一的数字。使用文件的行号是一个简单的选择。
InetSocketAddress socketAddress = serviceResolver.getSocketAddress();
connection = new J42PM_ClientConnection(socketAddress, responseHandler);
executorService.execute(new Runnable() {
@Override
public void run() {
TrafficStats.setThreadStatsTag(42); // <--
connection.run();
...
最后一个评论,如果您在堆栈跟踪中没有看到对代码的调用,那么您没有什么可以阻止违规行为。问题在另一个库中,除非您可以联系图书馆所有者,否则只需忽略违法行为。
我的解决方案是调用初始化:
private static final int THREAD_ID = 10000;
TrafficStats.setThreadStatsTag(THREAD_ID);
如果使用OKHTTP客户端,请创建Interceptor
并在intercept方法实现中添加到以下行
TrafficStats.setThreadStatsTag(Thread.currentThread().id.toInt())