Pregunta

Me han empezado a utilizar el StrictMode Android y encontrar que sería bueno tener siempre en funcionamiento durante el desarrollo y no sólo en una rama especial que creé en git. La razón por la que esta es mi requerimiento aplicaciones para funcionar con 1.6 o superior.

He leído en el blog de desarrolladores de Android que puedes configurarlo para que lo active a través de la reflexión. Me preguntaba cómo sería en realidad se parecen y si podría ser posible tener esta documentado aquí (o en otro lugar) en lugar de tener todo el mundo que quiere usar que funcione por sí mismas.

¿Fue útil?

Solución 2

Así que no quería esperar y decidió hacer el esfuerzo y aplicar esto a mí mismo. Básicamente se reduce a envolver StrictMode en una clase de contenedor y decidir en tiempo de ejecución a través de la reflexión si podemos activarlo.

He documentado en detalle en un blog publicar y la haya publicado en github .

Otros consejos

He leído el blog de Manfred pero no funciona si se establece versión de la plataforma de selección inferior a 2.3 porque el método StrictMode.enableDefaults(); no está disponible.

Aquí está mi solución que se basa totalmente en la reflexión y no genera errores de compilación:

    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);
    }

vi la entrada del blog. Dado que sólo quiere nunca StrictMode configuración como máximo una vez por archivo de Java, ¿tendría ningún sentido para simplificar el código para llamar para la configuración de la siguiente manera?

Aquí hay un StrictModeWrapper alternativo:

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());
        }
    }
}

A partir de su código, sólo tiene que hacer lo siguiente:

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

donde este es el contexto local, como su actividad o la aplicación o lo que sea. Esto parece funcionar para pre-2.3 de Android, y también le da el poder de utilizar los otros métodos de las clases Builder para StrictMode configurar exactamente como se desea.

He tirado juntos otra variación sobre el tema anterior, que he descrito en un blog aquí . La principal diferencia en mi enfoque es que también proporciona envoltorios para los objetos de disco y de política vm, por lo que fácilmente puede poner entre paréntesis código StrictMode-ofender con cambios en las políticas temporales. La retroalimentación es bienvenida.

El código para Pixel También añadió esta (basado en Android StrictMode ejemplo API):

            // 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);

Configurar el manifiesto de Android a algo como esto.

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

utilizar el siguiente código en onCreate Método.

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);

}

Nota:. Desactivar el aviso que ya está mirando qué versión del androide va a utilizar este código

Este código se activa si la versión de Android es superior a Android 2.2

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top