Каков жизненный цикл Android StrictMode? - PullRequest
4 голосов
/ 16 января 2011

Я пытаюсь минимизировать количество мест в моем коде, где мне нужно настроить StrictMode.Но я не уверен, прав ли я относительно следующего:

В документации для Android StrictMode сказано, что вы можете использовать его для приложений, действий и других компонентов.Я читал, что нежелательно расширять класс Application, и я бы предпочел не расширять Application только для того, чтобы включить StrictMode.Но я не думаю, что должен.

Есть две политики, которые вы можете использовать: ThreadPolicy (для потока) и VmPolicy (для всех потоков).Таким образом, может показаться, что если я настрою StrictMode в потоке один раз, не имеет значения, откуда я это сделаю, и о нарушениях в этом потоке будет сообщено впоследствии, независимо от других вызовов или нет, в StrictMode.Мне просто нужно позвонить откуда-нибудь, прежде чем могут произойти нарушения, которые я хочу обнаружить.И он должен быть настроен для любых новых потоков, которые создаются в моем приложении, которые я также хочу проверить.

Чего я хочу избежать, так это вызова методов build () больше, чем мне нужно.Помещение StrictMode в начало onCreate() во всех моих действиях означает, что build () будет вызываться несколько раз в этом потоке.Если у меня есть одно действие Launcher в моем приложении, настройка StrictMode в этом действии onCreate() должна быть достаточной для остальной части приложения.Это правда?

Во-вторых, если моя основная деятельность перезапускается, даже если приложение не умерло, технически необходимо повторно вызывать 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 ()и покончим с этим.И это должно работать на версиях Android до 2.3 тоже.Но это может не стоить того.Брэд, ты здесь?Спасибо.

Редактировать: Поскольку VmPolicy предназначен для всех потоков, технически мне нужно настроить его только один раз для каждого приложения, верно?Так что enableDefaults () тратит впустую усилия, чтобы переделать VmPolicy, когда он вызывается во второй, третий и т. Д. Раз?Опять же, может быть, это больше проблем, чем стоит пытаться избежать дополнительных звонков.

Ответы [ 2 ]

7 голосов
/ 19 января 2011

Да, VmPolicy предназначен для всего процесса, поэтому делать это один раз хорошо.Однако, больше времени обходится дешево, поэтому не беспокойтесь об этом.

И да, вам нужно сделать это только в onCreate () вашего действия main / launcher - это тот же "основной" поток, что ивсе остальные ваши компоненты.

2 голосов
/ 03 декабря 2013

Глядя на исходный код, вы видите, что он вызывается статически:

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;

Это означает, что вам нужно делать это только один раз для каждого приложения, например, при запуске / вводе приложения.

...