12

私は Android StrictMode の使用を開始しましたが、git で作成した特別なブランチだけでなく、開発中に常に実行することができれば素晴らしいと思います。私がこれを行った理由は、1.6 以降で実行するためのアプリの要件です。

リフレクションを介してアクティブ化するように設定できることを、Android開発者ブログで読みました。私はそれが実際にどのように見えるのか、また、それを使用したいすべての人に自分で解決してもらうのではなく、ここ (または他の場所) に文書化することが可能かどうか疑問に思っていました.

4

6 に答える 6

9

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);
    }
于 2011-11-15T15:04:20.473 に答える
8

だから私は待ちたくなかったので、努力して自分でこれを実装することにしました。基本的には、ラッパー クラスで StrictMode をラップし、それをアクティブ化できるかどうかをリフレクションによって実行時に決定することになります。

ブログ投稿で詳細に文書化し、 githubで利用できるようにしました。

于 2011-01-07T08:00:31.043 に答える
7

あなたのブログ記事を見ました。StrictMode を Java ファイルごとに最大 1 回だけセットアップしたいので、次のようにセットアップを呼び出すコードを単純化することは意味がありますか?

別の 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...");
}

これは、アクティビティやアプリケーションなどのローカル コンテキストです。これは、2.3 より前の Android で機能するようであり、Builder クラスの他のメソッドを使用して、StrictMode を希望どおりに正確に構成する機能も提供します。

于 2011-01-18T03:45:15.403 に答える
1

上記のテーマの別のバリエーションをまとめました。これについては、こちらのブログ投稿で概説しています。私のアプローチの主な違いは、ディスクおよび vm ポリシー オブジェクトのラッパーも提供されるため、StrictMode に違反するコードを一時的なポリシーの変更で簡単に囲むことができることです。フィードバックは大歓迎です。

于 2011-09-26T18:31:47.553 に答える
1

Pixel コードにこれも追加しました (StrictMode Android 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);
于 2012-07-31T20:35:42.717 に答える
0

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 以降の場合に有効になります

于 2012-09-04T14:55:31.337 に答える