与AsyncTask线程通信?处理程序不工作?
我有我的主 UI,并且有一个正在运行的 AsyncTask。我想与 AsyncTask 通信,让它在非 UI 线程上运行一些东西。所以我尝试做的是:
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");
}
}
};
...
}
但是,似乎当传入消息时,handleMessage() 实际上在 UI 线程中运行。我知道这一点是因为 runCommand() 阻塞了 5 秒,而我的 UI 最终没有响应 5 秒。
为什么handleMessage() 不在非UI 线程上运行?线程之间还有其他首选的通信方式吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在
doInBackground()
方法中创建处理程序对象。或者
如果处理程序独立于 Aysnctask,则可以将其放入单独的线程中。
编辑:
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 :
以下方法适用于 UI 线程
,或者您可以创建一个界面并注册事件
the following method works in UI thread
or you can create an interface and register for events
它在 UI 线程上运行,因为处理程序始终在创建它的线程上执行。在本例中,它将是 UI 线程。
我认为在你的情况下你并不真正需要处理程序。相反,只需在
WifiMon
任务中添加一些标志或适当的数据结构即可。从您现在调用处理程序的任何位置设置此标志和所需参数(当然,使用适当的保护)。如果您希望它在与任务本身相同的线程中执行,则必须在某个时刻中断 doInBackground 主要逻辑,此时只需检查您的标志即可。如果你想要另一个线程,只需引入一个方法来启动它即可。例如:
而不是
使用
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 interruptdoInBackground
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:
And instead of
use