Background:
This app is a simple Wifi manager, collecting/scanning and displaying results in a list view. Since this scan scans on a interval, I have created a thread and set a Thread.sleep(interval) between scans, so after processing is done, it sleeps for X milliseconds.
I have made a few "changes"/updates to my code, now my app goes into a ANR state with an debugger message "Signal Catcher"]: reacting to signal 3
Full Error:
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'
Problem:
Before Permissions added:
In the onCreate()
of main, I had my code to initiate my scan loop and start outputting data, this worked and was outputting data as expected.
Thread Code:
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();
After Permissions added:
After doing some research, I discovered that I should remove this Initiate scan
method from onCreate since it blocks any thread calls, I added it to onStart and added a method RunOnUITHD(Runnable r)
which will only access UI to update with essential code.
New Thread Code:
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 is defined by : handler = new Handler(context.getMainLooper());
RunOnUITHD
private void RunOnUITHD(Runnable runnable) {
handler.post(runnable);
}
I am still getting ANR (latest ANR Traces) and I am out of idea's, I have no idea what I am doing wrong.
UPDATE:
I logged every part of the main thread code, it is running as expected, looping and sleeping, but UI is not updating...
Adding Logging code to the new Runnable()
I notice the following:
adding a breakpoint to ThreadCounter of e.g. ThreadCounter==11
should result in 10 "Updaing Thread..." and "Finished update..." loops as seen from code below.
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");
}
});
Instead I only note 4 loops that are shown in log.
Running further tests, ThreadCounter==3
, loops logged = 1, allfurther tests results in 1 logged loop of Updating setText.
Since this thread is initiated via a custom method of checkPermissions()
in my @Override onStart()
, I show a toast message, followed by the checkPermissions
@Override
protected void onStart() {
super.onStart();
Toast.makeText(main.this, "Starting Service", Toast.LENGTH_SHORT).show();
logm("checking permissions in 'onStart'");
checkPermissions();
}
thoughout these tests, the Toast Message shows (does not disappear) and the setText updates on 1 loop, meaning the threadRefresh
TextView contains the following text : "# Refreshed Times : 1"