StrictModeについて
StrictModeについてandroid developer blogにあがってたので適当に訳してみたよ。
使うのは、以下の処理の場合。
- 通信やディスク読み書きを行うThread処理
- データ読み書きを行うSQLite処理
これら処理に時間がかかってANSsが発生するようなバグを検知して、ログにはいたりダイアログ出したりなどデバッグしやすくするモードのようです。現在SQLiteの場合はclose処理によっておこるリークのみ検知でまだ実装が十分でないです(将来拡張予定)。
ANRs*1が出たときのバグ調査って退屈だしめんどいよね。特にメソッドが複数絡んでるときとか(BinderとかContentResolverとかがServicesとかContentProviderを操作してるときなど)原因超特定しずらい。そこでStrictModeをつくったよ!
GingerBreadからはStrictModeAPIをつかえるよ。これはスレッドで実行できない処理やポリシーに違反したときの挙動を明示的にスレッドに指定できるよ。このポリシーは単純にスレッド固有の整数のビットマスクなんですよう。デフォルトではすべてが許可状態なので、明示的に指定しない限りデフォルトでは影響はないよ。
スレッドのポリシーなどで有効にできるフラグは以下の通り。
- ディスク書き込みの検出:detectDiskWrites()
- 読み込みディスクの検出:detectDiskReads()
- ネットワークの使用状況の検出:detectNetwork()
- すべて検出:detectAll()
- ポリシー違反のときログ出力:penaltyLog()
- ポリシー違反のときクラッシュ:penaltyDeath()
- ポリシー違反のときDropBoxへ出力:penaltyDropbox()
- ポリシー違反のときダイアログ表示:penaltyDialog()
StrictModeの有効にする方法はonCreate()に
public void onCreate() { if (DEVELOPER_MODE) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build()); } super.onCreate(); }の様に実装するか、単純に以下のようにする。
public void onCreate() { if (DEVELOPER_MODE) { StrictMode.enableDefaults(); } super.onCreate(); }Gingerbread以前(2.3以前)を対象とするなら、後者の構文で、リフレクションとかその他の方法を使う方法がまだ簡単かも。StrictMode.enableDefaults()をリフレクション使ってコールし、Gingerbread搭載の端末やエミュレータ環境で動かすとか。
penaltyLog()をつかうとadb logcatでターミナルに表示されるよ。penaltyDropbox()をつかうと以下のコマンドでdropBoxManagerへ書きだせる。
adb shell dumpsys dropbox data_app_strictmode --printスレッドやjava.util.concurrent.*に追加してHandler, AsyncTask, AsyncQueryHandler, IntentServiceなどのようなAndroid API をチェックできるよ。
StrictModeはどんどん実装拡大中だよ!ハニカムにもいっぱいいいのを用意したいので、何かあったらStackOverFlowにStrictModeタグつけていろいろ寄せてね!まってるよう!
VMについてもスレッドと同じ感じでフックできる。
StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build();
StrictMode.setVmPolicy(policy);
使えるメソッドは