背景:ANR
このアプリは、リストビュー内/走査と表示結果を収集し、単純な無線LANマネージャです。このスキャンはある間隔でスキャンするので、スレッドを作成し、スキャン間にThread.sleep(間隔)を設定しています。処理が完了した後、Xミリ秒間スリープします。
私は私のコードにいくつかの「変更」/更新を行ってきた、今私のアプリは、デバッガのメッセージとANR状態になり"Signal Catcher"]: reacting to signal 3
全エラー:
07-01 10:14:16.772 10027-10034/com.cynetstudios.wifimanager I/art: Thread[2,tid=10034,WaitingInMainSignalCatcherLoop,Thread*=0xa9007000,peer=0x12d1a0a0,"Signal Catcher"]: reacting to signal 3
07-01 10:14:17.101 10027-10034/com.cynetstudios.wifimanager I/art: Wrote stack traces to '/data/anr/traces.txt'
問題:
許可を前に追加:
メインのonCreate()
には、スキャンループを開始してデータを出力するコードがありましたが、これは正常にデータを出力していました。
スレッドコード:
t = new Thread(new Runnable() {
public void run() {
while (!bStopThread) {
ThreadCounter++;
if (bSafe) {
initWiFiArrays(); //Scans and inserts data into lists
CreateSetAdapter(); //Converts lists into adapter, and sets adapter to ExpandableListView
threadRefresh.setText("# Refreshed Times : " + String.valueOf(ThreadCounter));
writeResultsToFile(); //Write results to file
} else
stopScan();
try {
Thread.sleep(scanInterval);
} catch (Exception x) {
x.printStackTrace();
}
}
}
});
t.start();
権限が追加された後:
をいくつかの研究を行った後、私は、それ遮断任意のスレッド呼び出し以来のonCreateから私をこのInitiate scan
方法を削除する必要があることを発見しましたそれをonStartに追加し、メソッドRunOnUITHD(Runnable r)
を追加しました。このメソッドはUIにアクセスして必須コードで更新するだけです。
新しいスレッドコード:ハンドラがで定義され
t = new Thread(new Runnable() {
public void run() {
while (!bStopThread) {
ThreadCounter++;
if (bSafe) {
initWiFiArrays();
CreateSetAdapter();
RunOnUITHD(new Runnable() {
@Override
public void run() {
threadRefresh.setText("# Refreshed Times : " + String.valueOf(ThreadCounter));
}
});
writeResultsToFile();
} else
stopScan();
try {
Thread.sleep(scanInterval);
} catch (Exception x) {
x.printStackTrace();
}
}
}
});
t.start();
:handler = new Handler(context.getMainLooper());
RunOnUITHD
private void RunOnUITHD(Runnable runnable) {
handler.post(runnable);
}
私はまだANR(latest ANR Traces)を取得していますし、私は外にしていますアイデアの、私は何を間違っているのか分かりません。
UPDATE:
私はループして寝て、期待通りに実行されているが、UIがnew Runnable()
にロギングコードを追加しています...
を更新していない、メインスレッドのコードのすべての部分をログに記録しました私は次のことに気づきます:
例えばThreadCounterにブレークポイントを追加するThreadCounter==11
は、10の "Updaing Thread ..."と "Finished update ..."ループが発生するはずです。
RunOnUITHD(new Runnable() {
@Override
public void run() {
logm("POST HANDLER: updating Thread Refresh Text");
threadRefresh.setText("# Refreshed Times : " + String.valueOf(ThreadCounter));
logm("POST HANDLER: Finished update Thread Refresh Text");
}
});
代わりに、ログに表示される4つのループだけをメモします。
さらにテストを実行すると、ThreadCounter==3
、ループログ= 1、すべてのさらなるテスト結果が1セットのUpdating setTextのループを記録します。
このスレッドは私の@Override onStart()
にcheckPermissions()
のカスタムメソッドによって開始されているので、私はこれらのテストthoughout
@Override
protected void onStart() {
super.onStart();
Toast.makeText(main.this, "Starting Service", Toast.LENGTH_SHORT).show();
logm("checking permissions in 'onStart'");
checkPermissions();
}
checkPermissions続くトーストメッセージ、トーストメッセージショー(消えない)示し、 1つのループ上のsetTextの更新は、threadRefresh
のTextViewを意味し、次のテキストが含まれています:「#リフレッシュタイムズ:1」