StrictMode для версий с более низкой платформой
Я начал использовать Android StrictMode и обнаружил, что было бы здорово, чтобы он всегда работал во время разработки, а не только на специальном ядре, созданном в git. Причина, по которой я это сделал, - это требование моих приложений для работы с 1.6 и выше.
Я читал в блоге разработчиков Android, что вы можете настроить его, чтобы активировать его с помощью отражения. Мне просто интересно, как это будет выглядеть на самом деле, и если возможно, чтобы это было зарегистрировано здесь (или где-то еще), а не всем, кто хочет использовать его, выработайте сами.
Ответы
Ответ 1
Поэтому я не хотел ждать и решил приложить усилия и реализовать это сам. Это в основном сводится к тому, чтобы обернуть StrictMode в класс обертки и решить во время выполнения через отражение, если мы сможем его активировать.
Я подробно описал это в сообщении в блоге и сделал его доступным в github.
Ответ 2
Я прочитал пост в блоге Manfred, но он не работает, если вы установили версию целевой платформы ниже 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);
}
Ответ 3
Я видел ваш пост в блоге. Поскольку вы только когда-либо хотите настроить 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 точно так, как вам хотелось бы.
Ответ 4
Я собрал еще одну вариацию на тему выше, которую я изложил в сообщении в блоге здесь. Основное различие в моем подходе состоит в том, что он также предоставляет обертки для объектов политики диска и vm, так что вы легко можете скопировать StrictMode-нарушающий код с временными изменениями политики. Обратная связь приветствуется.
Ответ 5
В пиксельный код я также добавил это (на основе примера 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);
Ответ 6
Установите 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