StrictMode для версий с более низкой платформой - PullRequest
12 голосов
/ 06 января 2011

Я начал использовать Android StrictMode и обнаружил, что было бы здорово, чтобы он всегда работал во время разработки, а не только в специальной ветке, которую я создал в git.Причина, по которой я это сделал, - требование моего приложения работать с версией 1.6 и выше.

Я прочитал в блоге разработчика Android, что вы можете настроить его так, чтобы вы активировали его с помощью отражения.Мне было просто интересно, как это будет на самом деле выглядеть и возможно ли будет документировать это здесь (или где-то еще), вместо того, чтобы каждый, кто хочет использовать это, работал сам.

Ответы [ 6 ]

9 голосов
/ 15 ноября 2011

Я прочитал пост в блоге Манфреда, но он не работает, если вы установите версию целевой платформы ниже 2,3 , поскольку метод StrictMode.enableDefaults(); недоступен.

Вот мое решениеполностью полагается на отражение и не генерирует ошибки компиляции:

    try {
        Class<?> strictModeClass = Class.forName("android.os.StrictMode", true, Thread.currentThread()
                .getContextClassLoader());

        Class<?> threadPolicyClass = Class.forName("android.os.StrictMode$ThreadPolicy", true, Thread
                .currentThread().getContextClassLoader());

        Class<?> threadPolicyBuilderClass = Class.forName("android.os.StrictMode$ThreadPolicy$Builder", true,
                Thread.currentThread().getContextClassLoader());

        Method setThreadPolicyMethod = strictModeClass.getMethod("setThreadPolicy", threadPolicyClass);

        Method detectAllMethod = threadPolicyBuilderClass.getMethod("detectAll");
        Method penaltyMethod = threadPolicyBuilderClass.getMethod("penaltyLog");
        Method buildMethod = threadPolicyBuilderClass.getMethod("build");

        Constructor<?> threadPolicyBuilderConstructor = threadPolicyBuilderClass.getConstructor();
        Object threadPolicyBuilderObject = threadPolicyBuilderConstructor.newInstance();

        Object obj = detectAllMethod.invoke(threadPolicyBuilderObject);

        obj = penaltyMethod.invoke(obj);
        Object threadPolicyObject = buildMethod.invoke(obj);
        setThreadPolicyMethod.invoke(strictModeClass, threadPolicyObject);

    } catch (Exception ex) {
        Log.w(TAG, ex);
    }
8 голосов
/ 07 января 2011

Поэтому я не хотел ждать и решил приложить усилия и реализовать это сам. Это сводится к тому, чтобы обернуть StrictMode в класс-обертку и решить во время выполнения с помощью отражения, можем ли мы его активировать.

Я подробно описал это в блоге и сделал его доступным в github .

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

Я видел твой пост в блоге. Поскольку вы когда-либо хотите устанавливать StrictMode не более одного раза для каждого файла Java, имеет ли смысл упростить код для вызова установки следующим образом?

Вот альтернативный StrictModeWrapper:

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.StrictMode;

public class StrictModeWrapper {
    public static void init(Context context) {
        // check if android:debuggable is set to true
        int applicationFlags = context.getApplicationInfo().flags;
        if ((applicationFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectDiskReads()
                .detectDiskWrites()
                .detectNetwork()
                .penaltyLog()
                .build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectLeakedSqlLiteObjects()
                .penaltyLog()
                .penaltyDeath()
                .build());
        }
    }
}

Из вашего кода вам нужно всего лишь сделать следующее:

try {
    StrictModeWrapper.init(this);
}
catch(Throwable throwable) {
    Log.v("StrictMode", "... is not available. Punting...");
}

, где , это - локальный контекст, такой как ваша активность или приложение или что-то еще. Похоже, что это работает для Android до 2.3, а также дает вам возможность использовать другие методы классов Builder для точной настройки StrictMode.

1 голос
/ 01 августа 2012

К пиксельному коду я также добавил это (на примере Android API StrictMode):

            // VM policy
            Class<?> VmPolicyClass = Class.forName("android.os.StrictMode$VmPolicy", true, Thread.currentThread().getContextClassLoader());

            Class<?> VmPolicyBuilderClass = Class.forName("android.os.StrictMode$VmPolicy$Builder", true, Thread.currentThread().getContextClassLoader());

            Method setVmPolicyMethod = strictModeClass.getMethod("setVmPolicy", VmPolicyClass);

            Method detectLeakedSqlLiteObjectsMethod = VmPolicyBuilderClass.getMethod("detectLeakedSqlLiteObjects");
            Method detectLeakedClosableObjectsMethod = null; 
            try
            {
                detectLeakedClosableObjectsMethod = VmPolicyBuilderClass.getMethod("detectLeakedClosableObjects");
            }
            catch (Exception e) {}
            Method penaltyLogMethod = VmPolicyBuilderClass.getMethod("penaltyLog");
            Method penaltyDeathMethod = VmPolicyBuilderClass.getMethod("penaltyDeath");
            Method VmbuildMethod = VmPolicyBuilderClass.getMethod("build");

            Constructor<?> VmPolicyBuilderConstructor = VmPolicyBuilderClass.getConstructor();
            Object VmPolicyBuilderObject = VmPolicyBuilderConstructor.newInstance();

            Object Vmobj = detectLeakedSqlLiteObjectsMethod.invoke(VmPolicyBuilderObject);
            if (detectLeakedClosableObjectsMethod != null) Vmobj = detectLeakedClosableObjectsMethod.invoke(Vmobj);
            Vmobj = penaltyLogMethod.invoke(Vmobj);
            Vmobj = penaltyDeathMethod.invoke(Vmobj);

            Object VmPolicyObject = VmbuildMethod.invoke(Vmobj);
            setVmPolicyMethod.invoke(strictModeClass, VmPolicyObject);
1 голос
/ 26 сентября 2011

Я собрал еще одну вариацию на тему выше, которую я изложил в блоге здесь .Основным отличием моего подхода является то, что он также предоставляет оболочки для объектов политики disk и vm, так что вы легко можете заключить в код StrictMode-нарушитель временные изменения политики.Обратная связь приветствуется.

0 голосов
/ 04 сентября 2012

Установите для Манифеста Android что-то вроде этого.

< uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" android:maxSdkVersion="16"/ >

используйте приведенный ниже код в методе onCreate.

int SDK_INT = android.os.Build.VERSION.SDK_INT;

} if (SDK_INT>8){

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

StrictMode.setThreadPolicy(policy);

}

Примечание. Отключите предупреждение, поскольку вы уже проверяете, какая версияAndroid будет использовать этот код.

этот код будет активирован, если версия Android выше Android 2.2

...