与AsyncTask线程通信?处理程序不工作?

时间:2011-08-29 03:51:10

标签: android multithreading communication android-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线程上运行?线程之间是否还有其他一些首选的通信方式?

3 个答案:

答案 0 :(得分:2)

doInBackground()方法中创建处理程序对象。
或者
如果处理程序独立于Aysnctask,则可以将处理程序放在单独的线程中。

编辑:

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);

答案 1 :(得分:0)

以下方法适用于UI线程

onProgressUpdate

或者您可以创建一个界面并注册活动

答案 2 :(得分:0)

它在UI线程上运行,因为处理程序总是在创建它的线程上执行。在这种情况下,它将是UI线程。

我认为在你的情况下,你真的不需要处理程序。相反,只需在WifiMon任务中使用一些标记或适当的数据结构。从您现在称为处理程序的任何地方设置此标志和必需参数(当然,使用适当的警卫)。如果您希望它在与任务本身相同的线程中执行,那么您必须在某个时刻中断doInBackground主逻辑,此时只需检查您的标记。

如果你想要另一个线程,只需引入一个方法来启动它。例如:

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();
   }
}

而不是

wifimon._handler.post(...);

使用

wifimon.startScan();