androidandroid-strictmode

Finding what violated StrictMode policy


I've enabled StrictMode in my app and it's causing a few crashes as expected. How can I find out where in my code I'm violating these policies?

This is the stack trace:

E/AndroidRuntime(19523): FATAL EXCEPTION: main
E/AndroidRuntime(19523): android.os.StrictMode$StrictModeViolation: policy=95 violation=2
E/AndroidRuntime(19523):        at android.os.StrictMode.executeDeathPenalty(StrictMode.java:1326)
E/AndroidRuntime(19523):        at android.os.StrictMode.access$1300(StrictMode.java:111)
E/AndroidRuntime(19523):        at android.os.StrictMode$AndroidBlockGuardPolicy.handleViolation(StrictMode.java:1319)
E/AndroidRuntime(19523):        at android.os.StrictMode$AndroidBlockGuardPolicy$1.run(StrictMode.java:1206)
E/AndroidRuntime(19523):        at android.os.Handler.handleCallback(Handler.java:605)
E/AndroidRuntime(19523):        at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(19523):        at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(19523):        at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime(19523):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(19523):        at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(19523):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
E/AndroidRuntime(19523):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
E/AndroidRuntime(19523):        at dalvik.system.NativeStart.main(Native Method)

but as you can see ... it's not very useful ... I know who killed my app, I need to know why!

Thanks.


Solution

  • You need to call penaltyLog() on your StrictMode.ThreadPolicy.Builder, so that it will show you the underlying reason as well as stopping your app.

    Here's what you probably have currently:

    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
    .detectDiskReads()
    .detectDiskWrites()
    .detectNetwork()
    .penaltyDeath()
    .build());
    

    If you call the network on the main thread, you'll get this exception which is hard to understand:

    E/AndroidRuntime(8752): android.os.StrictMode$StrictModeViolation: policy=71 violation=4
    E/AndroidRuntime(8752):     at android.os.StrictMode.executeDeathPenalty(StrictMode.java:1311)
    

    If you then add penaltyLog() to your policy...

    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
    .detectDiskReads()
    .detectDiskWrites()
    .detectNetwork()
    .penaltyLog()
    .penaltyDeath()
    .build());
    

    then you will see a much more helpful message like the one below. This will be in the LogCat output.

    D/StrictMode(8810): StrictMode policy violation; ~duration=2956 ms: android.os.StrictMode$StrictModeNetworkViolation: policy=87 violation=4
    D/StrictMode(8810):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1090)
    

    If you look closely, you'll see that this stack trace will lead you to the code which is causing the StrictMode violation.