Java android广播接收器OnReceive()延迟导致错误

Java android广播接收器OnReceive()延迟导致错误,java,android,Java,Android,我的广播接收器侦听WiFi ssid更改,如果ssid更改,它将返回布尔值WifiChanged true。我在另一个活动中检查此布尔值,该活动根据返回的值更改列表,无论该值为true还是false。默认情况下,布尔值为false 我故意更改wifi,这将触发广播接收器将布尔值返回为true,并相应地设置列表,但实际发生的情况是,我的列表基于布尔值false进行更改,因为广播接收器需要一段时间才能返回值。在下面的日志中,您可以看到布尔值为false,大约在0.58秒后,ssid发生变化。到那时已

我的广播接收器侦听WiFi ssid更改,如果ssid更改,它将返回布尔值WifiChanged true。我在另一个活动中检查此布尔值,该活动根据返回的值更改列表,无论该值为true还是false。默认情况下,布尔值为false

我故意更改wifi,这将触发广播接收器将布尔值返回为true,并相应地设置列表,但实际发生的情况是,我的列表基于布尔值false进行更改,因为广播接收器需要一段时间才能返回值。在下面的日志中,您可以看到布尔值为false,大约在0.58秒后,ssid发生变化。到那时已经太晚了

08-08 16:43:54.487: D/PlayerManager(20733): Did Wi-Fi Changed: false
   |
   |
   |
08-08 16:43:55.047: V/ConnectionChangeReceiver(20733): onReceive(Context context, Intent intent)
08-08 16:43:55.077: D/ConnectionChangeReceiver(20733): ssid changed from s_ssid="Walter_Meth_Lab" to newSsid="Kings_Landing"
这是我的OnReceive()

这是我使用布尔值的另一个活动

boolean WifiChanged = ConnectionChangeReceiver.getInstance().WifiChanged();
        Log.d(TAG, "Did Wi-Fi Changed:" + WifiChanged);
        if (WifiChanged) {
            //Do Something

        }

如果更改了Wi-Fi ssid,则列表应根据WifiChanged true更改,但它始终会更改为WifiChanged false,因为ChangeReceiver()不会及时返回true,并且会使用默认的false。

有很多方法可以完成此操作

我更喜欢使用
LocalBroadcastManager

这将如何工作:与其让活动询问信息,不如让
ConnectionChangeReceiver
在信息可用时传递信息。一旦
ConnectionChangeReceiver
处理完接收到的
intent
,它就会发出
本地
广播。如果你的活动是活跃的,并且在倾听,它就会对此做出反应

// Snippet from your `ConnectionChangeReceiver # onReceive(...)` method
if (connectionInfo != null) {
    newSsid = connectionInfo.getSSID();
    if ((newSsid != null) && (s_ssid != null) && (newSsid.compareTo(s_ssid) != 0)) {
        Log.d(TAG, "ssid changed from s_ssid=" + s_ssid + " to newSsid=" + newSsid);
        mHasWifiChanged = true;

        // We can send a local broadcast now
        // Note that the String `"com.my.app.wifi.WIFI_RELATED_CHANGE"` can be 
        // customized to your preference
        Intent localIntent = new Intent("com.my.app.wifi.WIFI_RELATED_CHANGE");

        // Including this extra is redundant here since `mHasWifiChanged` will
        // always be true at this point. I am including it for example sake.
        // Again, notice that the key `"com.my.app.wifi.WIFI_HAS_CHANGED"` can
        // be customized
        localIntent.putExtra("com.my.app.wifi.WIFI_HAS_CHANGED", mHasWifiChanged);

        // Broadcasts the Intent to receivers in this app
        LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent);
    }
}
在活动端:在活动中创建一个
BroadcastReceiver
,并将其设置为侦听操作
“com.my.app.wifi.wifi\u相关\u更改”
。此字符串值必须与从
连接ChangeReceiver\onReceive(…)
发送广播时使用的字符串值相同:

您应该将
BroadcastReceiver
声明为类成员。这将允许您适当地注册和注销
BroadcastReceiver
:在
onResume()中注册和在
onPause()中注销

在活动的
onResume()
中,注册此接收器以侦听操作
com.my.app.wifi.wifi\u相关的\u更改

@Override
public void onResume() {
    super.onResume();

    // Activity has come to foreground. Register to listen for changes to wifi state.

    // Create an IntentFilter with action `com.my.app.wifi.WIFI_RELATED_CHANGE`
    IntentFilter intentFilter = new IntentFilter("com.my.app.wifi.WIFI_RELATED_CHANGE");

    // Register your broadcastreceiver to receive broadcasts 
    // with action `com.my.app.wifi.WIFI_RELATED_CHANGE`
    LocalBroadcastManager.getInstance(this)
                         .registerReceiver(wifiRelatedChangeListener, intentFilter);
}
onPause()
中注销接收器:

请注意,您可以在任意多个活动中声明一个接收方,例如
wifirelatedchangelister
。广播从
连接ChangeReceiver#onReceive(…)
发送一次。无论哪个活动在前台/在该点收听,都将接收该广播并对其采取行动

到那时已经太晚了

08-08 16:43:54.487: D/PlayerManager(20733): Did Wi-Fi Changed: false
   |
   |
   |
08-08 16:43:55.047: V/ConnectionChangeReceiver(20733): onReceive(Context context, Intent intent)
08-08 16:43:55.077: D/ConnectionChangeReceiver(20733): ssid changed from s_ssid="Walter_Meth_Lab" to newSsid="Kings_Landing"

上述解决方案中不存在此问题

您的方法不正确。您的广播接收器应向您的活动发送消息,然后您的活动应使用“onNewIntent”方法检查WiFi状态。然后,如果您正在接收机中设置一个静态变量(您可能不应该这样做),您可以检查它,但最好只发送一个带有WiFi状态的布尔“额外”活动


问题是您的UI线程比后台线程快得多。因此,如果一个活动正在响应一个接收者也在响应的事件,Android很可能会优先处理该活动而不是后台线程。

你能发布更多代码吗?如何使用和定义变量
mHasWifiChanged
会对此产生重大影响。。。此外,根据您的代码,您可能需要另一种解决方案。您似乎应该使用
ConnectionChangeListener
在发生更改时通知活动,而不是让活动随意检查状态。您可以提供这样做的代码示例吗?
@Override
public void onResume() {
    super.onResume();

    // Activity has come to foreground. Register to listen for changes to wifi state.

    // Create an IntentFilter with action `com.my.app.wifi.WIFI_RELATED_CHANGE`
    IntentFilter intentFilter = new IntentFilter("com.my.app.wifi.WIFI_RELATED_CHANGE");

    // Register your broadcastreceiver to receive broadcasts 
    // with action `com.my.app.wifi.WIFI_RELATED_CHANGE`
    LocalBroadcastManager.getInstance(this)
                         .registerReceiver(wifiRelatedChangeListener, intentFilter);
}
@Override
public void onPause() {
    super.onPause();

    // Activity is going to background. No need to listen anymore
    LocalBroadcastManager.getInstance(this).unregisterReceiver(wifiRelatedChangeListener);
}