Android StrictMode的生命周期是什么?

时间:2011-01-16 20:41:16

标签: android android-strictmode

我正在尝试最小化我需要设置StrictMode的代码中的位置数。但是我不确定我对下列内容是否正确。

Android的StrictMode文档说您可以将它用于应用程序,活动和其他组件。我已经读过扩展Application类是不可取的,我不想仅仅为了启用StrictMode而扩展Application。但我认为不得不这样做。

您可以使用两种策略:ThreadPolicy(用于线程)和VmPolicy(用于所有线程)。所以看起来如果我在一个线程上设置一次StrictMode,那么我从哪里开始并不重要,并且此后将在该线程上报告违规,而不管StrictMode上是否有其他调用。我只需要在我想要检测到的违规行为之前从某个地方调用它。并且需要为我想要检查的应用程序中创建的任何新线程设置它。

我认为我想避免的是调用build()方法而不是我需要的。在我的所有活动中将StrictMode放在onCreate()的开头意味着build()将在该线程上被多次调用。如果我的应用程序中有一个Launcher活动,那么在该活动的onCreate()中设置StrictMode应该足以满足应用程序的其余部分。这是真的吗?

其次,如果我的主要活动重新启动,即使应用程序没有死亡,技术上是否需要再次调用StrictMode?或者我的线程仍设置为报告违规?我认为在StrictMode周围做一个包装类的类可能有一些价值,如下所示:

public class MyStrictModeSettings {
    static private List<Long> setThreads = new ArrayList<Long>();

    // Prevent instantiation of this class
    private MyStrictModeSettings() {}

    static public synchronized void init() {
        try {
            Long tid = Thread.currentThread().getId();
            if(!setThreads.contains(tid)) {
                setThreads.add(tid);
                Class sMode = Class.forName("android.os.StrictMode");
                Method enableDefaults = sMode.getMethod("enableDefaults");
                enableDefaults.invoke(null);
            }
        }
        catch(Exception e) {
            // StrictMode not supported on this device, punt
            Log.v("StrictMode", "... not supported. Skipping...");
        }
    }
}

这样,在我的主要活动的onCreate()中,我可以简单地调用MyStrictModeSettings.init()并完成它。它也适用于2.3之前的Android版本。但它可能不值得。布拉德,你呢?感谢。

编辑:由于VmPolicy适用于所有线程,从技术上讲,我只需要为每个应用程序设置一次,对吧?因此,当调用第二,第三等时间时,enableDefaults()会浪费精力重做VmPolicy吗?再一次,也许比试图避免额外的电话更麻烦。

2 个答案:

答案 0 :(得分:7)

是的,VmPolicy适用于整个过程,所以一次就可以了。但是,更多的时间是便宜的,所以不要对它有所了解。

是的,您只需要在主/启动器活动的onCreate()中执行此操作 - 这与所有其他组件的“主”线程相同。

答案 1 :(得分:2)

查看源代码,您可以看到它是静态调用的:

public static void setVmPolicy(final VmPolicy policy) {
    synchronized (StrictMode.class) {
        sVmPolicy = policy;
        sVmPolicyMask = policy.mask;
        setCloseGuardEnabled(vmClosableObjectLeaksEnabled());

        Looper looper = Looper.getMainLooper();
        if (looper != null) {
            MessageQueue mq = looper.mQueue;
            if (policy.classInstanceLimit.size() == 0 ||
                (sVmPolicyMask & VM_PENALTY_MASK) == 0) {
                mq.removeIdleHandler(sProcessIdleHandler);
                sIsIdlerRegistered = false;
            } else if (!sIsIdlerRegistered) {
                mq.addIdleHandler(sProcessIdleHandler);
                sIsIdlerRegistered = true;
            }
        }
    }
}

策略本身也是静态存储的 - 类中没有非静态成员变量。

    private static volatile VmPolicy sVmPolicy = VmPolicy.LAX;

这意味着您只需要为每个应用程序执行一次,例如在应用程序的启动/输入活动中。