سؤال

لقد بدأت في استخدام نظام Android StrictMode وأجد أنه سيكون من الرائع أن يعمل دائمًا أثناء التطوير وليس فقط على فرع خاص قمت بإنشائه في GIT. السبب في أنني فعلت هذا هو شرط تطبيقاتي للتشغيل مع 1.6 وما فوق.

قرأت على مدونة Android Developer التي يمكنك إعدادها حتى تقوم بتفعيلها عبر التأمل. كنت أتساءل فقط كيف سيبدو ذلك في الواقع ، وإذا كان من الممكن توثيق هذا هنا (أو في مكان آخر) بدلاً من وجود كل من يريد استخدامه.

هل كانت مفيدة؟

المحلول 2

لذلك لم أرغب في الانتظار وقررت بذل الجهد وتنفيذ هذا بنفسي. إنه يتلخص بشكل أساسي في لف الصارمة في فئة Wrapper واتخاذ قرار في وقت التشغيل عبر الانعكاس إذا كان بإمكاننا تنشيطه.

لقد وثقتها بالتفصيل في منشور مدونة وجعلها متوفرة في جيثب.

نصائح أخرى

لقد قرأت منشور مدونة مانفريد ولكنه لا يعمل إذا قمت بتعيين إصدار النظام الأساسي المستهدف أقل من 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 على الأكثر مرة واحدة لكل ملف Java ، فهل من المنطقي تبسيط الكود للدعوة إلى الإعداد على النحو التالي؟

إليك مجموعة بديلة بديلة:

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 ، ويمنحك أيضًا قوة استخدام الأساليب الأخرى لفئات البناء لتكوين StrictMode تمامًا كما تريد.

لقد ألقيت معًا تباينًا آخر في السمة أعلاه ، والتي حددتها في منشور مدونة هنا. الفرق الرئيسي في نهجي هو أنه يوفر أيضًا أغلفة لكائنات سياسة القرص و VM ، بحيث يمكنك بسهولة عرض رمز مدورة مع تغييرات مؤقتة في السياسة. ردود الفعل موضع ترحيب.

إلى رمز البكسل ، أضفت هذا أيضًا (استنادًا إلى مثال API StrictMode Android):

            // 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 على شيء مثل هذا.

< 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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top