2011-07-14 24 views
30

Tengo una pregunta muy simple:Inflar una vista en un subproceso de fondo

es o no es posible inflar una vista (no añadirla al diseño) en un subproceso en segundo plano (por ejemplo: en el doInBackground de un AsyncTask)?

Sé que es posible, porque he implementado la mayoría de las actividades en mi solicitud de esta manera y nunca tuvo un problema, hasta que tuve este problema en un Galaxy S: Android: android.view.InflateException: Binary XML file line #13: Error inflating class <unknown> in SAMSUNG Galaxy S

me han dicho que yo debería no inflar Views en hilos de fondo, pero ¿cuáles son las razones específicas y por qué mi enfoque funciona en la mayoría de los dispositivos, pero no en Galaxy S?

Respuesta

36

El LayoutInflater no hace suposiciones sobre qué hilo se ejecuta. Y nada se menciona sobre esto en su documentación. También su código parece ser thread-agnostic.

Por otro lado, las vistas creadas por LayoutInflater pueden crear instancias Handler en sus constructores. Bueno, probablemente no deberían hacer eso, pero no es necesario que creen/usen Handler s en sus constructores.

Mi conjetura es que Samsung Galaxy S tuvo algunas modificaciones en su EditText que de alguna manera desencadena la creación de Handler (según registro de bloqueo de su otra instancia cuestión de GestureDetector se crea una instancia que a su vez crea nueva Handler). Si bien la implementación predeterminada no hace esto.


En general, diría que debido a que no hay ningún requisito explícito para View s no usar Handler s y s Looper en sus constructores no se puede asumir que inflan Vistas desde la interfaz de usuario de rosca no es seguro.

En realidad, puede crear HandlerThread e intentar inflar View s dentro de él. Pero yo diría que esto es muy arriesgado, ya que en el ejemplo de Samsung Galaxy S, la vista supone que este hilo estará activo durante toda la vida View y procesará todos los mensajes usando su Looper. Lo cual podría ocasionar un bloqueo posterior.

+6

He reproducido este mismo problema en un Galaxy Nexus con el último firmware de stock (a partir de esta publicación). Inflar las vistas en el fondo definitivamente ya no es una opción. –

+0

HandlerThread reenviar El mensaje a MainLooper debería resolver este problema – wanpen

2

Es o no es posible inflar una vista (no agregarla al diseño) en una cadena de fondo (por ejemplo, en el doInBackground de una AsyncTask)?

Posible, sí. ¿Recomendado? No.Como se menciona en la documentación:

Por lo tanto, no son más que dos reglas a un modelo único hilo de Android:

  1. no bloquean el hilo de interfaz de usuario
  2. No acceda a la caja de herramientas de Android UI desde fuera del hilo UI

a través de: Processes and Threads

6

Con la última versión de la versión gratuita, puede usar android.support.v4.view.AsyncLayoutInflater para inflar las vistas de forma asíncrona. Tenga cuidado sin embargo que puede vuelve a los inflar el hilo de interfaz de usuario si no se cumplen los requisitos específicos:

Para un diseño para inflar de forma asíncrona tiene que tener un padre cuyo generateLayoutParams (AttributeSet) es seguro para subprocesos y todo el Las vistas que se construyen como parte de la inflación no deben crear controladores ni llamar a myLooper(). Si el diseño que intenta inflarse no puede construirse de forma asíncrona por la razón que sea, AsyncLayoutInflater volverá automáticamente a inflarse en el subproceso de la interfaz de usuario.

Cuestiones relacionadas