Crashlytics with StrictMode enabled (detect all) gives “untagged socket detected”

試著忘記壹切 提交于 2019-12-31 03:58:05

问题


I've tried adding Crashlytics to my app, which already has StrictMode enabled with detectAll(). The result was Untagged socket detected; use TrafficStats.setThreadSocketTag() to track all network usage.

Full Stack:

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.

I tried to create a new project and it was the same, the code in MainActivity in the test project:

@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());
    }
}

I did see that Okhttp has this issue (as well as other libs) but I do not know if that is relevant.
I'll add a workaround as an answer (basically don't use detectAll()), but I wonder if there is a proper solution for this, maybe there's a way to add the tag to the socket?


回答1:


A workaround is to not use detectAll(), I've copied the the code of detectAll() (from Crashlytics) and modified it; however I had to remove part of code since there are classes that are inaccessible.
I'm not a huge fan of this workaround but I'm not sure there's a better solution.

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;
}

Option two - remove the penaltyDeath() from the VmPolicy - this is what I'm currently doing:

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());
}



回答2:


Api 28 has introduced:

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

So at least you can listen for specific violations (like UntaggedSocketViolation) and choose to ignore them. Of course, it would be better if Crashlytics were to tag their sockets appropriately.



来源:https://stackoverflow.com/questions/53195068/crashlytics-with-strictmode-enabled-detect-all-gives-untagged-socket-detected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!