从接收器通知线程

时间:2012-09-10 20:22:01

标签: java android multithreading broadcastreceiver

这是我的主线:

Thread t = new Thread(){

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i = 0; i < passes.length; i++){
            progPass.setProgress(i);
            WifiConfiguration wc = new WifiConfiguration();
            wc.SSID = "\"" + dbw.getSsid() + "\"";
            wc.preSharedKey  = "\"" + passes[i] + "\"";
            wc.status = WifiConfiguration.Status.ENABLED;   
            wc = configureCapabs(wc, dbw.getCapability());
            int res = wifi.addNetwork(wc);
            //Toast.makeText(this, "add Network returned " + res , Toast.LENGTH_SHORT).show();
            boolean b = wifi.enableNetwork(res, true);        
            //Toast.makeText(this, "enableNetwork returned " + b , Toast.LENGTH_SHORT).show();
            if(!b) continue;
            try {
                synchronized(this){
                    this.wait();
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            boolean fin = wifi.getConnectionInfo() != null;
            if(fin) break;
        }
        progPass.dismiss();
        this.interrupt();
    }

};

它会检查wifi是否使用一种更常见的密码。当等待线等待来自广播接收器的通知时,这是其代码:

public class ConnectivityActionReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
        NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
        if(networkInfo.isConnected()) {
            // Wifi is connected
            Toast.makeText(context, "Wifi is connected: " + String.valueOf(networkInfo), Toast.LENGTH_SHORT).show();
            synchronized(this){
                notifyAll();
            }
        }
    } else if(intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
        NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
        if(networkInfo.getType() == ConnectivityManager.TYPE_WIFI && ! networkInfo.isConnected()) {
            // Wifi is disconnected
            Toast.makeText(context, "Wifi is disconnected: " + String.valueOf(networkInfo), Toast.LENGTH_SHORT).show();
        }
    } else if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)){
        int esr = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, 0);
        if(esr != 0){
            Toast.makeText(context, Integer.toString(esr), Toast.LENGTH_LONG).show();
            synchronized(this){
                notifyAll();
            }
        }

    }
}

这里注册了Manifest:

 <receiver
        android:name="ConnectivityActionReceiver"
        android:enabled="true"
        android:label="ConnectivityActionReceiver" >
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            <action android:name="android.net.wifi.STATE_CHANGE" />
            <action android:name="android.net.wifi.supplicant.STATE_CHANGE" />
        </intent-filter>
    </receiver>

它与线程在同一个类中有一个实例:

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    IntentFilter filter = new IntentFilter();
    this.registerReceiver(car, filter);
}

应该出现在onReceive方法中的toast出现,意味着收到了消息,但是通知没有到达线程,这意味着它等待了。

1 个答案:

答案 0 :(得分:2)

您正在使用两个不同的对象进行同步!一个是线程对象,一个是ConnectivityActionReceiver。当您使用this时:

 synchronized(this){
      this.wait();
 }

您正在锁定当前实例,因此您将锁定您案例中的不同实例。

解决方案是在一个共同的,全局可见的对象上调用wait/notify

final Object signal = new Object();

// in the waiting thread
synchronized(signal) {
    signal.wait();
}

// in the signaling thread
synchronized(signal) {
    signal.notifyAll();
}