【问题标题】:Crashlytics with StrictMode enabled (detect all) gives "untagged socket detected"启用 StrictMode(检测全部)的 Crashlytics 给出“检测到未标记的套接字”
【发布时间】:2018-11-07 17:54:58
【问题描述】:

我尝试将Crashlytics 添加到我的应用程序中,该应用程序已经启用了StrictModedetectAll()。结果是Untagged socket detected; use TrafficStats.setThreadSocketTag() to track all network usage

全栈:

E/StrictMode: null
java.lang.Throwable: Untagged socket detected; use TrafficStats.setThreadSocketTag() to track all network usage
    at android.os.StrictMode.onUntaggedSocket(StrictMode.java:2012)
    at com.android.server.NetworkManagementSocketTagger.tag(NetworkManagementSocketTagger.java:78)
    at libcore.io.BlockGuardOs.tagSocket(BlockGuardOs.java:47)
    at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:310)
    at libcore.io.IoBridge.socket(IoBridge.java:667)
    at java.net.PlainSocketImpl.socketCreate(PlainSocketImpl.java:116)
    at java.net.AbstractPlainSocketImpl.create(AbstractPlainSocketImpl.java:98)
    at java.net.Socket.createImpl(Socket.java:484)
    at java.net.Socket.getImpl(Socket.java:547)
    at java.net.Socket.setSoTimeout(Socket.java:1175)
    at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:139)
    at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:112)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:184)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:538)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(Unknown Source:0)
    at io.fabric.sdk.android.services.network.HttpRequest.code(HttpRequest.java:1357)
    at io.fabric.sdk.android.services.settings.DefaultSettingsSpiCall.handleResponse(DefaultSettingsSpiCall.java:104)
    at io.fabric.sdk.android.services.settings.DefaultSettingsSpiCall.invoke(DefaultSettingsSpiCall.java:88)
    at io.fabric.sdk.android.services.settings.DefaultSettingsController.loadSettingsData(DefaultSettingsController.java:88)
    at io.fabric.sdk.android.services.settings.DefaultSettingsController.loadSettingsData(DefaultSettingsController.java:65)
    at io.fabric.sdk.android.services.settings.Settings.loadSettingsData(Settings.java:153)
    at io.fabric.sdk.android.Onboarding.retrieveSettingsData(Onboarding.java:126)
    at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:99)
    at io.fabric.sdk.android.Onboarding.doInBackground(Onboarding.java:45)
    at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:63)
    at io.fabric.sdk.android.InitializationTask.doInBackground(InitializationTask.java:28)
    at io.fabric.sdk.android.services.concurrency.AsyncTask$2.call(AsyncTask.java:311)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
W/System.err: StrictMode VmPolicy violation with POLICY_DEATH; shutting down.

我尝试新建一个项目,还是一样,测试项目中MainActivity中的代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    setCrashlytics();
    setStrictMode();
}

private void setCrashlytics() {
    Fabric.with(this, new Crashlytics());
}

private void setStrictMode() {
    if (BuildConfig.DEBUG) {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectAll()
                .penaltyLog()
                .build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectAll()
                .penaltyLog()
                .penaltyDeath()
                .build());
    }
}

我确实看到了 Okhttp has this issue(以及其他库),但我不知道这是否相关。
我将添加一个解决方法作为答案(基本上不使用detectAll()),但我想知道是否有适当的解决方案,也许有办法将标签添加到套接字?

【问题讨论】:

    标签: android crashlytics-android android-strictmode


    【解决方案1】:

    解决方法是不使用detectAll(),我复制了detectAll() 的代码(来自Crashlytics)并对其进行了修改;但是我不得不删除部分代码,因为有些类无法访问。
    我不是这种解决方法的忠实拥护者,但我不确定是否有更好的解决方案。

    private void setStrictMode() {
        if (BuildConfig.DEBUG) {
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectAll()   // detectDiskReads, detectDiskWrites, detectNetwork
                    .penaltyLog()
                    .build());
    
            StrictMode.setVmPolicy(getStrictModeBuilder().build());
        }
    }
    
    private StrictMode.VmPolicy.Builder getStrictModeBuilder() {
        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    
        builder.detectLeakedSqlLiteObjects();
    
        final int sdkInt = Build.VERSION.SDK_INT;
        if (sdkInt >= Build.VERSION_CODES.HONEYCOMB) {
            builder.detectActivityLeaks();
            builder.detectLeakedClosableObjects();
        }
    
        if (sdkInt >= Build.VERSION_CODES.JELLY_BEAN) {
            builder.detectLeakedRegistrationObjects();
        }
    
        if (sdkInt >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            builder.detectFileUriExposure();
        }
    
        if (sdkInt >= Build.VERSION_CODES.O) {
            builder.detectContentUriWithoutPermission();
        }
    
        builder.penaltyLog().penaltyDeath();
        return builder;
    }
    

    选项二 - 从VmPolicy 中删除penaltyDeath() - 这就是我目前正在做的事情:

    private void setStrictMode() {
    if (BuildConfig.DEBUG) {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectAll()   // detectDiskReads, detectDiskWrites, detectNetwork
                .penaltyLog()
                .build());
    
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .build());
    }
    

    【讨论】:

    • 这可以用 Kotlin 写吗?
    • 有人还在 github 问题中提出了这种解决方法:TrafficStats.setThreadStatsTag(10000);——基本上只是在创建任何套接字之前将标签设置为随机数。但老实说,这应该从 detectAll 中排除,或者所有这些库都应该修复它。
    【解决方案2】:

    Api 28 已经引入:

    public StrictMode.VmPolicy.Builder penaltyListener (Executor executor,
                    StrictMode.OnVmViolationListener listener)
    

    因此,至少您可以监听特定的违规行为(例如 UntaggedSocketViolation)并选择忽略它们。当然,如果 Crashlytics 能够适当地标记他们的套接字会更好。

    【讨论】:

    • 我们如何忽略它们?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    • 2014-10-21
    • 1970-01-01
    相关资源
    最近更新 更多