2011-10-31 18 views
6

Estoy viendo que mi hilo de llamada cuelga en código nativo al llamar a WifiManager.enableNetwork(). Hasta ahora, solo he podido reproducir este truco en la tableta Motorola Xoom con Android 3.2.1. He probado en muchos otros teléfonos y tabletas (todos funcionan con Froyo o Gingerbread) y no he visto el problema. El Xoom es el único dispositivo dual-core que tengo que probar (y he reproducido el problema en 2 Xooms diferentes), así que me siento como si estuviera tropezando con algunos requisitos de subprocesamiento de Android muy sutiles cuando se conecta con WifiManager. El seguimiento de la pila donde mi hilo llamando cuelga es:Thread cuelgue en la red de 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 

Mi aplicación está intentando conectarse a un punto de acceso wifi conocido, realizar algunas pruebas, a continuación, volver a conectar el dispositivo a su punto de acceso original (si estaba previamente conectado). Antes de establecer la conexión, ya hemos verificado que wifi está habilitado y hemos realizado una exploración para verificar que se encuentre nuestro SSID del punto de acceso. Este código para establecer la conexión se está ejecutando en un AsyncTask y se ve algo como esto:

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

Este código se basa en el código de menú de configuración WiFi en el código de fuente abierta Android Gingerbread. ¿Hay algo acerca de llamar a WifiManager.enableNetwork() que me falta? ¿Tiene que ejecutarse en un hilo en particular? He intentado garantizar que enableNetwork() se invoque en la secuencia de la interfaz de usuario (trasladando la lógica al receptor de difusión). Esto pareció ayudar un poco, pero aún así pude reproducir el truco. Tal vez esto es algo específico de Honeycomb? En este momento, estos 2 Xooms son los únicos dispositivos Honeycomb que tengo disponibles para probar, por lo que son los únicos puntos de datos que tengo.

G

+0

¿Alguna suerte en eso? Tengo el mismo problema. Acabo de encontrar información que quizás connectNetwork debería usarse en su lugar, pero aún no hay AIDL oficial para eso, así que tendrías que hackearla :( – pprzemek

+0

Sí, tenía que hacer exactamente eso. Utilicé la reflexión para acceder al "oculto" "API (solo para Honeycomb y posterior) y nunca he tenido un problema desde. –

+0

He planteado [informe de error] (http://code.google.com/p/android/issues/detail?id=34070). –

Respuesta

1

Este es de hecho un problema de firmware específico a 3. * (parece).

He visto esto suceder en un Asus Transformer TF101, y Sony Tablet S (ambos con 3. *, eso fue hace algún tiempo).

A partir de 3.0, hay nuevas API para conectarse a WiFi, que no requieren el uso de enableNetwork en lotes (para habilitar todas las redes excepto la actual).

Más sobre esas API, lo que pude deducir a partir del código fuente 4.0:

  • Están marcados con "@hide"
  • Son utilizados por la aplicación Ajustes
  • aún no están documentados como de 4,1
  • Ellos contrario, entre el 3 * y 4 * de tiempo de ejecución

Mi recomendación es tratar de utilizar las API a través de la reflexión. Dado que son utilizados por la aplicación de configuración, funcionan.

+0

No estoy seguro de si se trata de un problema de firmware por lo que sé que sucede en HTC Jetsream, Samsung Galaxy Tab 10.1, Asus RF101, Sony Tablet S y Motorola Xoom. Parece un error general en Honeycomb: he encontrado varios informes en Android emite db alrededor de la sincronización del método wifiManager.Parece que Honeycomb no puede sincronizar eliminar, agregar, habilitar y guardar desde múltiples hilos. Ver [problema] (http://code.google.com/p/android/issues/detail?id=34070) –

Cuestiones relacionadas