【问题标题】:Finding what violated StrictMode policy查找违反 StrictMode 政策的内容
【发布时间】:2012-04-04 13:46:11
【问题描述】:

我在我的应用中启用了 StrictMode,它会导致一些预期的崩溃。 如何找出我在代码中的哪些地方违反了这些政策?

这是堆栈跟踪:

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)

但是正如你所看到的......它不是很有用......我知道是谁杀死了我的应用程序,我需要知道为什么!

谢谢。

【问题讨论】:

  • 您是如何启用 SrictMode 的?请粘贴代码以便我们检查。
  • DetectAll.penaltyLog().penaltyDeath() 两者。在下面查看您的回复,看来我需要在我的日志过滤器中添加“StrictMode”:)

标签: android android-strictmode


【解决方案1】:

您需要在您的 StrictMode.ThreadPolicy.Builder 上调用 penaltyLog(),以便它向您显示根本原因以及停止您的应用程序。

以下是您目前可能拥有的:

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

如果你在主线程上调用网络,你会得到这个很难理解的异常:

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

如果您随后将 penaltyLog() 添加到您的策略中...

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

然后您将看到一条更有帮助的消息,如下所示。这将在 LogCat 输出中。

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)

如果您仔细观察,您会发现此堆栈跟踪将引导您找到导致 StrictMode 违规的代码。

【讨论】:

  • 注意:这 IS 我正在做的事情,但是您的日志条目显示我需要调整我的日志过滤器(这是我在尝试跌倒时所怀疑的睡着了:))。你赢了蛋糕:)谢谢
  • 好吧,它看起来对我没有多大帮助。我怎么知道它崩溃的代码是什么?
  • 我应该看多远?即使在使用显微镜之后,我也没有看到任何有用的信息。
【解决方案2】:

StrictMode (android.os.StrictMode) 类可用于启用和执行可以检查和报告的各种策略。

当您在主 UI 线程上执行磁盘写入时,这可能是执行磁盘写入冲突时发生的 StrictMode 冲突。要解决它,您需要将磁盘写入移出主线程。

如果此时您无法移动代码,您可以禁用对部分代码的检查。

显式添加代码以在违规代码执行之前停止检查特定规则违规,然后在违规代码完成后重新启用对该规则的检测。

StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy();
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old)
    .permitDiskWrites()
    .build());
doCorrectStuffThatWritesToDisk();
StrictMode.setThreadPolicy(old);

源码取自here.

【讨论】:

【解决方案3】:

每当我看到这样的堆栈跟踪时,我总是会查看我的 Activity 生命周期事件。检查你的 onCreate、onResume、onPause 方法中发生了什么(有更多的生命周期事件,但这些是常见的)。在这些方法中设置断点,看看哪个方法以这条致命消息终止。然后从那里拿走。

尝试使用

来捕捉这个错误
protected void onResume() {
  super.onResume();
  try {
    codeThatCrashesBecauseOfStrictMode();
  } catch(Throwable tr) { Log.e(tr); }
}

这应该是调试此问题的一个很好的起点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-19
    • 2021-03-14
    • 2019-04-06
    • 2016-03-03
    • 1970-01-01
    • 2016-01-14
    • 2021-09-27
    相关资源
    最近更新 更多