Práctica recomendada para que el cliente android se comunique con un servidor mediante subprocesos

Estoy construyendo una aplicación para Android que se comunica con un servidor de forma regular, siempre y cuando la aplicación esté en ejecución.

Hago esto iniciando una conexión al servidor cuando la aplicación comienza, entonces tengo un thread separado para recibir los mensajes llamados ReceiverThread , este thread lee el mensaje del socket , lo analiza, y lo remite a la parte apropiada de la aplicación.

Este thread ejecuta en un bucle, leyendo lo que tiene que leer y luego bloquea en el comando read() hasta que lleguen nuevos datos, por lo que pasa la mayor parte del tiempo bloqueado.

Puedo enviar mensajes a través de un hilo diferente, llamado SenderThread . Lo que me pregunto es: ¿Debo estructurar el SenderThread de una manera similar? Significado debo mantener algún formulario una cola para este hilo, dejarlo enviar todos los mensajes en la cola y luego bloquear hasta nuevos mensajes entrar en la cola, o debería sólo iniciar una nueva instancia del hilo cada vez que un mensaje debe ser enviado , Dejar que envíe el mensaje y luego "morir"? Estoy inclinado hacia el primer enfoque, pero no sé qué es realmente mejor tanto en términos de rendimiento (mantener un hilo bloqueado en la memoria frente inicializar nuevos hilos), y en términos de corrección de código.

También, ya que todas mis actividades deben ser capaces de enviar y recibir mensajes que estoy sosteniendo una referencia a ambos hilos en mi clase de Application , es que un enfoque aceptable o debo implementarlo de manera diferente?

Un problema que he encontrado con esto es que a veces si cierro mi aplicación y ejecutarlo de nuevo en realidad tengo dos instancias de ReceiverThread, por lo que obtener algunos mensajes dos veces.

Supongo que esto es porque mi aplicación no se cerró realmente y el hilo anterior estaba todavía activo (bloqueado en la operación read() ), y cuando abrí la aplicación de nuevo un nuevo hilo se inicializó, pero ambos estaban conectados al servidor Por lo que el servidor envió el mensaje a ambos. ¿Algún consejo sobre cómo solucionar este problema, o sobre cómo reorganizarlo completamente para que sea correcto?

Traté de buscar estas preguntas, pero encontró algunos ejemplos conflictivos para mi primera pregunta, y nada que sea lo suficientemente útil y se aplica a mi segunda pregunta …

1. Su enfoque es correcto, si realmente necesita mantener una conexión abierta entre el servidor y el cliente en todo momento a todo costo. Sin embargo, yo utilizaría una conexión asíncrona, como enviar una solicitud HTTP al servidor y luego obtener una respuesta siempre que el servidor se siente como él.

Si necesita que el servidor responda al cliente más tarde, pero no sabe cuándo, también puede consultar el marco de Google Cloud Messaging , que le proporciona una forma transparente y consistente de enviar mensajes pequeños a sus clientes desde Su servidor.

Tienes que considerar algunas cosas, cuando estás desarrollando una aplicación móvil.

  1. Un teléfono inteligente no tiene una cantidad interminable de batería.

  2. La conexión a Internet de un teléfono inteligente es algo volátil y perderás la conexión a Internet en momentos diferentes.

Cuando mantiene una conexión directa con el servidor todo el tiempo, su aplicación sigue enviando paquetes keep-alive, lo que significa que chupar el teléfono seco bastante rápido. Cuando la conexión a Internet es tan inestable como lo hace en la banda ancha móvil, perderá la conexión a veces y tendrá que recuperarse de esto. Por lo tanto, si utiliza TCP porque desea asegurarse de que sus paquetes se reciben, puede volver a enviar los mismos paquetes muchas veces y así obtener una gran cantidad de gastos generales.

También puede ejecutar a los problemas de roscado en el lado del servidor, si se abren los temas en el servidor por su cuenta, que suena como. Digamos que tiene 200 clientes conectándose al servidor al mismo tiempo. Cada cliente tiene 1 subproceso abierto en el servidor. Si el servidor necesita servir 200 subprocesos diferentes al mismo tiempo, esto podría ser una tarea que consuma mucho rendimiento para el servidor al final y necesitará hacer mucho trabajo por su cuenta también.

2. Cuando salga de su aplicación, tendrá que limpiar después de usted. Esto debe hacerse en el método onPause de la Activity que está activa.

Esto significa, eliminando todos los subprocesos activos (o al menos interrumpiéndolos), guardando el estado de su interfaz de usuario (si es necesario) y vaciando y cerrando cualquier conexión abierta al servidor que tenga.

En cuanto a usar Threads , recomendaría usar algunas de las herramientas de generación de subprocesos como los controladores o la implementación de AsyncTask .

Si realmente piensas que Thread es el camino a seguir, definitivamente recomendaría usar un patrón Singleton como un "manager" para tu enhebrado.

Este gestor controlará tus subprocesos, por lo que no terminará con más de un Thread hablando con el servidor en un momento dado, aunque esté en otra parte de la aplicación.

En cuanto a la implementación de la clase Application , vea la documentación de la clase Application :

Clase base para aquellos que necesitan mantener el estado de la aplicación global. Puede proporcionar su propia implementación especificando su nombre en la etiqueta de AndroidManifest.xml, que hará que esa clase se instancia para usted cuando se crea el proceso para su aplicación / paquete.

Normalmente no es necesario subclasificar la Aplicación. En la mayoría de las situaciones, los singletons estáticos pueden proporcionar la misma funcionalidad de una manera más modular.

Por lo tanto, mantenerse alejado de la implementación de su propia clase de Application es recomendable, sin embargo, si deja que una de sus Activities inicialice su propia clase Singleton para administrar los Threads y las conexiones que podría (puede ser) ejecutar en problemas, ya que la inicialización de singleton podría " "A la Activity específica y así, si la Activity específica se elimina de la pantalla y se detiene, puede ser destruida y, por lo tanto, el singleton puede ser eliminado también. Por lo tanto, la inicialización del singleton dentro de la implementación de la Application podría ser útil.

Lo siento por la pared de texto, pero su pregunta es bastante "abierta", así que he tratado de darle una pregunta algo abierta – espero que ayuda 😉

  • Bitwise "&" en un largo?
  • Problemas al cambiar la posición de un ImageView en Android
  • Cómo hacer claro (vacío / sin valores) spinner on clearbutton
  • Problemas de serialización de RealmList (Realm / Gson / Intent)
  • ¿Cómo puedo detectar un clic en un oyente onTouch?
  • Recuperar la dirección MAC de forma programática - Android
  • ¿Cómo puedo hacer que este zip rxjava funcione en paralelo?
  • Devolver un ArrayList y String asyncTask
  • Cordova / Phonegap Android - Java / Ant problema en la construcción?
  • Asynctask ArrayList objeto que no pasa de doInBackground a onPostExecute
  • Reconocimiento de voz Java como androides
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.