2011-10-31 31 views
6

我看到我的调用线程在调用WifiManager.enableNetwork()时挂在本机代码中。到目前为止,我只能在运行Android 3.2.1的摩托罗拉Xoom平板电脑上重现这种情况。我已经测试过其他几款手机和平板电脑(全部运行Froyo或姜饼),并没有看到问题。 Xoom是我必须测试的唯一双核设备(并且我已经在2个不同的Xooms上重现了这个问题),所以我觉得我在与WifiManager进行接口时陷入了一些非常微妙的Android线程需求。在我的调用线程挂起堆栈跟踪为:线程挂在WifiManager.enableNetwork()

BinderProxy.transact(int, Parcel, Parcel, int) line: not available [native method] 
    IWifiManager$Stub$Proxy.enableNetwork(int, boolean) line: 513 
    WifiManager.enableNetwork(int, boolean) line: 587 

我的应用程序试图连接到一个已知的WiFi接入点,进行一些测试,然后将设备重新连接到原来的接入点(如果它以前连接的)。在建立连接之前,我们已经验证wifi已启用,并且我们已执行扫描以验证我们的接入点SSID是否已找到。此代码建立连接在的AsyncTask运行,看起来是这样的:

... 
private WifiManager mWifiManager; 
private List<WifiConfiguration> mConfiguredNets = new ArrayList<WifiConfiguration>(); 
private Object mConnectMonitor = new Object(); 
private NetworkInfo.State mNetworkState = State.UNKNOWN; 

private final BroadcastReceiver mConnectionStateReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context inContext, final Intent inIntent) { 
     final String action = inIntent.getAction(); 
     if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { 
      NetworkInfo ni = 
       (NetworkInfo)inIntent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 
      State state = ni.getState(); 
      if (state == State.CONNECTED) { 
       synchronized (mConnectMonitor) { 
        mNetworkState = state; 
        mConnectMonitor.notify(); 
       } 
      } 
     } 
    } 
}; 

public void runninInAsyncTask(Context activityContext, int networkID) { 

    mWifiManager = (WifiManager)activityContext.getSystemService(Context.WIFI_SERVICE); 

    // Register our broadcast receiver to get network state change events 
    IntentFilter ifilter = new IntentFilter(); 
    ifilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 
    activityContext.registerReceiver(mConnectionStateReceiver, ifilter); 

    // Get a list of our currently configured networks so we can re-enable 
    // them after connecting to the desired network 
    mConfiguredNets = mWifiManager.getConfiguredNetworks(); 

    // Enable our network and disable all others 
    mWifiManager.enableNetwork(networkId, true); 

    // Start the reconnection process to connect to our desired network 
    synchronized (mConnectMonitor) { 
     mWifiManager.reconnect(); 
     mConnectMonitor.wait(60000); 
     if (mNetworkState != State.CONNECTED) { 
      Log.e(TAG, "Problems connecting to desired network!"); 
     } 
     else { 
      Log.e(TAG, "Successfully connected to desired network!"); 
     } 
    }    

    // Re-enable all of our previously configured networks 
    for (WifiConfiguration wifiConfig : mConfiguredNets) 
    {    
     if (wifiConfig.status != Status.ENABLED) { 
      mWifiManager.enableNetwork(wifiConfig.networkId, false); 
     } 
    }    
} 
... 

此代码是基于Android的姜饼开放源代码的WLAN设置菜单中的代码。有没有关于我缺少调用WifiManager.enableNetwork()的任何事情?它是否必须在特定的线程上运行?我已经尝试确保在UI线程上调用enableNetwork()(通过将逻辑移动到广播接收器)。这似乎有一点帮助,但我仍然能够重现这一悬念。也许这是Honeycomb专用的东西?现在,这两个Xooms是我可用于测试的唯一蜂窝设备,因此它们是我拥有的唯一数据点。

G

+0

对此有什么好运?有同样的问题。只是发现一些信息,可能连接网络应该用来代替,但没有官方的AIDL,所以你需要破解它:( – pprzemek

+0

是的,我必须做到这一点,我用反射来访问“隐藏“API(仅适用于Honeycomb和更高版本),并且从此我从来没有遇到过任何问题。 –

+0

我提出了[bug报告](http://code.google.com/p/android/issues/detail?id=34070)。 –

回答

1

这确实是一个特定于3的固件问题*(看起来)。

我在华硕变压器TF101和索尼Tablet S(两者都带有3. *,前一段时间)都看到过这种情况。

从3.0开始,有一些用于连接到WiFi的新API,它们不需要批量使用enableNetwork(以启用除当前网络之外的所有网络)。

更多关于这些API,我可以收集来自4.0的源代码:

  • 他们都标有“@hide”
  • 它们通过设置应用
  • 他们还没有使用记录作为4.1
  • 他们的3 *和4 *运行

我的建议是尝试并使用这些API之间有所改变通过反思。由于它们由“设置”应用使用,因此它们可以工作。

+0

我不知道它是否是固件问题,因为我知道它发生在HTC Jetsream,三星Galaxy Tab 10.1,华硕RF101,索尼Tablet S和摩托罗拉Xoom。这似乎是蜂窝中的一个常见错误 - 我发现有多个报告在android问题数据库周围的wifiManager方法同步。听起来像Honeycomb无法同步删除,添加,启用和保存多个线程。请参阅[问题](http://code.google.com/p/android/issues/detail?id=34070) –