StrictMode для версий с более низкой платформой

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

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

Solutions Collecting From Web of "StrictMode для версий с более низкой платформой"

Я прочитал сообщение в блоге Манфреда, но он не работает, если вы установили версию целевой платформы ниже 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); } 

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

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

Я видел ваш блог. Поскольку вы только хотите установить 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..."); } 

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

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

Для пиксельного кода я также добавил это (на основе примера Android Android 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); 

Установите Android Manifest на что-то вроде этого.

 < 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