communication with AsyncTask thread? Handler not working?
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?
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);
the following method works in UI thread
onProgressUpdate
or you can create an interface and register for events
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();
精彩评论