Reputation: 7555
I have my main UI, and I have an AsyncTask running. I want to communicate to the AsyncTask to have it run something on the non-UI thread. So what I tried doing was:
protected class WifiMon extends AsyncTask<Context, Integer, String>
{
Context parent;
CoexiSyst coexisyst;
private static final String WIMON_TAG = "WiFiMonitor";
private int PCAP_HDR_SIZE = 16;
private int _scan_pkts_left;
public Handler _handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// We invoke a scan, and then read in all of the packets
// captured from the scan.
if(msg.obj == ThreadMessages.WIFI_SCAN_START) {
Log.d(TAG, "Got message to start Wifi scan");
int start_rxpkts = getRxPacketCount();
runCommand("/data/data/com.gnychis.coexisyst/files/iw dev wlan0 scan");
_scan_pkts_left = getRxPacketCount() - start_rxpkts;
Log.d(TAG, "Finished Wifi scan");
}
}
};
...
}
However, it seems like when an incoming message comes in, handleMessage() actually runs in the UI thread. I know this because runCommand() blocks for 5 seconds, and my UI ends up unresponsive for 5 seconds.
Why is handleMessage() not running on the non-UI thread? Is there some other preferred way of communication between the threads?
Upvotes: 3
Views: 2646
Reputation: 24732
It runs on UI thread because, handler is executed always on the thread that created it. In this case it would be UI thread.
I think that in you case you don't really need handler. Instead, just have some flag or appropriate data structure in your WifiMon
task. Set this flag and required parameters from whatever place you call your handler now (with appropriate guards, of course). If you want it to be executed in the same thread as the task itself, you must at some point interrupt doInBackground
main logic anyway and at this point, just check your flag.
If you want another thread, just introduce a method to start it. For example:
protected class WifiMon extends AsyncTask<Context, Integer, String>
{
public void startScan() {
Thread t = new Thread() {
public void run() {
// Scan here and read/update properties of WifiMon
}
};
t.start();
}
}
And instead of
wifimon._handler.post(...);
use
wifimon.startScan();
Upvotes: 0
Reputation: 24235
Create the handler object in doInBackground()
method.
Or
You can put the handler in a separate thread if it is independent of the Aysnctask.
EDIT :
mHandlerThread = new HandlerThread("some_name");
mHandlerThread.start();
/* we need to wait to get the looper instance */
while(!mHandlerThread.isAlive()) {};
mHandler = new Handler(mHandlerThread.getLooper(), null);
Upvotes: 2
Reputation: 9993
the following method works in UI thread
onProgressUpdate
or you can create an interface and register for events
Upvotes: 0