AndroidのStrictModeのライフサイクルは何ですか?
-
11-10-2019 - |
質問
StrictModeをセットアップする必要があるコードの場所の数を最小限に抑えようとしています。しかし、私が正しいかどうかはわかりません。
AndroidのStrictModeのドキュメントでは、アプリケーション、アクティビティ、その他のコンポーネントに使用できると述べています。アプリケーションクラスを拡張することは望ましくないことを読みました。また、StrictModeを有効にするためだけにアプリケーションを拡張したくないと読みました。しかし、私はしなければならないと思います。
使用できる2つのポリシーがあります。スレッドポリティ(スレッド用)とvmpolicy(すべてのスレッド用)。したがって、スレッドで一度StrictModeをセットアップした場合、それがどこにあるのかは問題ではなく、その後、他の呼び出しに関係なくそのスレッドで違反が報告されるように思われます。検出したい違反が発生する前に、どこかから電話する必要があります。また、私のアプリケーションで作成された新しいスレッドにセットアップする必要があります。
私が避けたいと思うのは、必要以上にbuild()メソッドを呼び出すことです。の最初にstrictmodeを置きます onCreate()
私のすべてのアクティビティにおいて、Build()がそのスレッドで複数回呼び出されることを意味します。アプリケーションに1つのランチャーアクティビティがある場合、そのアクティビティでStrictModeを設定します onCreate()
残りのアプリケーションには十分でなければなりません。本当?
第二に、アプリケーションが死ななかったとしても、私の主なアクティビティが再起動された場合、StrictModeを再度呼び出す必要がありますか?それとも、私のスレッドはまだ違反を報告するために設定されていますか?私は、StrictModeの周りでラッパータイプのクラスを行うことにある程度の価値があるかもしれないと思っていました:
public class MyStrictModeSettings {
static private List<Long> setThreads = new ArrayList<Long>();
// Prevent instantiation of this class
private MyStrictModeSettings() {}
static public synchronized void init() {
try {
Long tid = Thread.currentThread().getId();
if(!setThreads.contains(tid)) {
setThreads.add(tid);
Class sMode = Class.forName("android.os.StrictMode");
Method enableDefaults = sMode.getMethod("enableDefaults");
enableDefaults.invoke(null);
}
}
catch(Exception e) {
// StrictMode not supported on this device, punt
Log.v("StrictMode", "... not supported. Skipping...");
}
}
}
そうすれば、私のメインアクティビティのOnCreate()では、mystrictModesettings.init()を呼び出して、それを実行できます。また、2.3よりも前にAndroidバージョンで動作するはずです。しかし、それは価値がないかもしれません。ブラッド、あなたはそこにいますか?ありがとう。
編集: vmpolicyはすべてのスレッド用であるため、技術的にはアプリケーションごとに1回だけセットする必要がありますよね? EnabledEfaults()は、VMPolicyが2番目、3番目などと呼ばれるときにVmpolicyをやり直す努力を無駄にしていますか?繰り返しになりますが、余分な電話を避けようとすることよりも、それはもっとトラブルです。
解決
はい、vmpolicyはプロセス全体であるため、一度それを行うことは問題ありません。しかし、もっと安いので、それについて心配しないでください。
そして、はい、メイン/ランチャーアクティビティのoncreate()でそれを行う必要があります---それは他のすべてのコンポーネントと同じ「メイン」スレッドです。
他のヒント
ソースコードを見ると、それは静的に呼ばれていることがわかります:
public static void setVmPolicy(final VmPolicy policy) {
synchronized (StrictMode.class) {
sVmPolicy = policy;
sVmPolicyMask = policy.mask;
setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
Looper looper = Looper.getMainLooper();
if (looper != null) {
MessageQueue mq = looper.mQueue;
if (policy.classInstanceLimit.size() == 0 ||
(sVmPolicyMask & VM_PENALTY_MASK) == 0) {
mq.removeIdleHandler(sProcessIdleHandler);
sIsIdlerRegistered = false;
} else if (!sIsIdlerRegistered) {
mq.addIdleHandler(sProcessIdleHandler);
sIsIdlerRegistered = true;
}
}
}
}
また、ポリシー自体も静的に保存されます - クラスには非静的なメンバー変数はありません。
private static volatile VmPolicy sVmPolicy = VmPolicy.LAX;
これは、アプリケーションの起動/エントリアクティビティなど、アプリケーションごとに1回だけ行う必要があることを意味します。