【问题标题】:Notifying multiple Activities of network connection通知网络连接的多个活动
【发布时间】:2014-02-27 05:00:13
【问题描述】:

我的 android 项目中有大约七个活动,并且在所有七个活动中,我想监控网络断开连接。我创建了一个 networkreceiver 类,它在启用或禁用 wifi 时接收通知。

public class NetworkReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent arg1) {
    ConnectivityManager conMan = (ConnectivityManager) context.
        getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo netInfo = conMan.getActiveNetworkInfo();
    if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI) 
        Log.d("WifiReceiver", "Have Wifi Connection");
    else
        Log.d("WifiReceiver", "Don't have Wifi Connection");    
    }   
}

在清单中

<receiver android:name=".NetworkReceiver" >
    <intent-filter>
         <action android:name="android.net.wifi.STATE_CHANGE" />
         <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

我的问题是,由于我将它创建为一个单独的类,我没有得到如何通知每个活动 wifi 未启用。或者我是否必须在每个活动中创建一个网络接收器作为内部类。

【问题讨论】:

    标签: android wifi android-wifi wifimanager


    【解决方案1】:

    嗯,我认为处理程序的答案有点臭 - 最大的味道是你必须保留广播接收器的实例 - 一个由请求实例化的清单接收器。而是在清单中删除注册并在您的活动的 Sart/Stop 上注册取消注册接收器 - 无需为此使接收器成为内部类。取消注册 onStop 可能无法在 Froyo 上运行,但是嘿 - 我们在 KitKat 上

    这种方式在 IMO 上更好,因为您将接收器置于它应该发出信号的活动中,而不是在接收器类中混合活动和接收器逻辑。另外,如果您设法保留对接收者的引用,请告诉我-我很好奇

    【讨论】:

    • 但是当我收到网络不可用的通知时如何停止任务。
    • @wqrahd:停止哪个任务?
    • 假设我正在下载文件并在网络断开之间。然后如何停止或暂停下载任务以及何时重新连接网络恢复或重新启动已停止或暂停的任务。
    • @wqrahd:接收者可能会调用类的静态方法——但静态意味着麻烦。接收者毕竟可能是一个内部类,并且可以访问 Activity 的方法/字段 - 如果您必须对所有 7 重复,这会很痛苦。最简单:接收者更改内部首选项(调用 getDefaultSharedPreferences(context) in i> onReceive) 和活动都在倾听这样的变化。您甚至可能有一个实现共享首选项侦听器并定义常见行为的基本活动 - 哎呀,您可以在这个基本活动中拥有 onStart/onStop
    • 假设我有 sharedpreference 变量。我正在发出一个 http 请求。所以我必须在while循环中发出这个请求并检查“while variable true make http call”吗?
    【解决方案2】:

    一个不错的解决方案如下。您的广播接收器有一个对象数组(每个活动一个),当通知到达时,您循环访问这些对象以让它们知道 WiFi 状态已更改。

    详情

    首先,您的广播接收器实例应该对所有活动都可用(通过静态变量、单例或您想要的任何方式)。

    第二,每个activity都有一个Handler对象来处理事件,我们称之为mHandler

    第三,广播接收器有一个Handler数组,我们称之为'mHandlerArray'。

    在您的广播接收器类中有一个 Handler 对象数组。每个活动通过传递一个指向每个活动拥有的mHandler 的指针来订阅自己。您的广播接收器可以有两种方法:一种是注册,另一种是取消注册。

    所以,每个Activity都实现了onResume()onPause()

    void onResume()
    {
        mBroadcastReceiver.register(mHandler);
    }
    
    void onPause()
    {
        mBroadcastReceiver.unregister(mHandler);
    }
    

    广播接收器这样做:

    void register(Handler handler)
    {
        mHandlerArray.add(handler);
    }
    
    void register(Handler handler)
    {
        mHandlerArray.remove(handler);
    }
    

    最后,当 WiFi 状态发生变化时,从您的 onReceive() 遍历 mHandlerArray 并向每个 Handler 发送一条消息。每个 Activity 都会相应地处理消息。

    【讨论】:

    • 如果其中一些活动已经被破坏。那么会发生什么?
    • onPause() 取消注册处理程序,因此当 Activity 被销毁时,处理程序将不再在数组中。
    • 我的意思是在任何广播之前,一些活动会被破坏所以它会导致问题。因为活动会在某些参数上被破坏
    • 没问题,销毁的活动不会被通知。我在我的一个项目中使用了这种技术,它非常优雅(我承认这不是最简单的)。
    • 是否将处理程序声明为静态导致问题。?
    【解决方案3】:

    如果你在清单中注册你的接收器,那么只有定义的类可以接收广播信息。所以,你可以在应用类中定义注册和注销选项,然后广播接收器方法可以保留你的活动类(哪个活动类需要知道网络状态)

    【讨论】:

    • then only defined class can receive the broadcast info ???澄清并让我知道(或删除)
    【解决方案4】:

    创建一个单独的类 Networkinfo 并创建一个方法来检查 Internet 连接。

    你想在哪里检查互联网,然后你用那个类的对象调用这个方法。 下面的链接将有助于检测连接性。

    How do I see if Wi-Fi is connected on Android?

    祝你好运。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      • 2015-01-23
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      相关资源
      最近更新 更多