Java – Android: Hilo que se llama (ejecutar) dos veces

Quisiera alguna ayuda con respecto a Java – Android MultiThreading

Mientras aprendía a desarrollar mi aplicación de una manera multi-threading con el fin de aprovechar la cada vez mayor multi-core dispositivos de cuota de mercado (la mayoría de los dispositivos son cuádruple núcleo ahora, algunos incluso octo-core), corrí en una situación donde mi Los subprocesos están llamando dos veces o ejecutándose dos veces.

Simplemente no sé por qué y cómo.

[EDIT 3] AsyncTask el problema: llamé a AsyncTask del método onResume() . Aunque mi aplicación no perdió el foco (lo que significaría una llamada a onPause() luego de nuevo a onResume() al volver del foco en cuyo caso mis hilos se ejecutarían dos veces) durante las pruebas, resolví el problema alejando la llamada A FetchFriendsList a otro lugar. Hasta ahora tan bueno, pero ya que en mis pruebas de la aplicación no perder el enfoque o tal vez lo hizo, pero no pude presenciarlo (!), Creo que hay otra razón detrás de lo que yo diría que mi problema no está enteramente resuelto .. Al menos por el momento. Funciona sin embargo. Quizás resolví el problema pero no sé cómo 🙁 [end of EDIT 3]

Estoy implementando el último SDK de Facebook y lo estoy usando para buscar la lista de amigos del usuario final, que parece hacer el trabajo. Dado que estoy ejecutando esta operación en un AsyncTask, no estoy usando request.executeAsync() . En su lugar, estoy usando request.executeAndWait() . Facebook JavaDoc indica que este método sólo debe utilizarse si no estoy en el hilo principal de la interfaz de usuario que es mi caso de lo contrario me gustaría obtener una NetworkOnMainThreadException .

De todos modos, aquí es donde el comportamiento extraño está sucediendo.

 private final ArrayList<GraphUser> userFriendsList = new ArrayList<GraphUser>(); public final void fetchFriendsList() { if (this.session != null && this.session.isOpened()) { final Request requestUserFriendsList = Request.newMyFriendsRequest( this.session, new Request.GraphUserListCallback() public final void onCompleted(final List<GraphUser> users, final Response response) { if (users != null && users.size() > 0) { Log.v("Retrieved Friends List -> ", String.valueOf(users.size())); userFriendsList.addAll(users); } } } ); if (this.asyncFlag) requestUserFriendsList.executeAsync(); else requestUserFriendsList.executeAndWait(); } } 

En mi caso, asyncFlag se establece en false porque necesito hacer cosas sincrónicamente en ese orden específico:

  1. Obtener lista de amigos de usuario (no en el hilo principal (UI))
  2. Guardar lista de amigos en el dispositivo (subproceso nuevo)
  3. Guardar lista de amigos en un servidor (nuevo subproceso separado)

Siguiendo este patrón, la línea userFriendsList.addAll(users); Se llama dos veces . En el logcat, el Log.v se muestra dos veces más, y finalmente buscando con el depurador, el contenido de la lista de amigos del usuario está hecho de duplicados.

Pero eso no es todo … los pasos 2 y 3 son, de hecho, dos subprocesos separados que se crean y se generan dentro del mismo método: public final void asyncSaveFacebookFriendsList() .

Y adivina qué, este método es incluso llamado dos veces !

Solo porque ?

Al principio estaba llamando al método para el paso 2 y 3 así:

 [...] userFriendsList.addAll(users); asyncSaveFacebookFriendsList(); // it was private before [...] 

Aquí es donde el problema comenzó cuando ambas líneas se ejecutaban dos veces.

Así que pensé, bien, lo llamaré más tarde de esta manera:

 [...] fetchFriendsList(); asyncSaveFacebookFriendsList(); // it is now public [...] 

Pero la cuestión sigue estando pendiente. Si no llamo a public final void asyncSaveFacebookFriendsList() , entonces nada se ejecuta dos veces .

¿Por qué ocurre este problema? ¿Hay algo que no recibí en Java Threads?

No creo que esto esté de alguna manera relacionado con el SDK de Facebook, ya que siguiendo el mismo patrón (y también al mismo tiempo), tengo los mismos problemas al recopilar y almacenar la lista de amigos de Twitter del usuario final.

Así que creo que estoy haciendo algo mal. ¿Alguien tiene alguna idea en qué caso posible un hilo se llama dos veces?

Nota : todos los subprocesos se inician de esta manera: thread.start() . No estoy usando ningún ThreadPool ni el ExecutorService .

En caso de que necesite más contexto de fondo: Contenido de AsyncTask: (no hay necesidad de preguntarse por qué vacío y largo, elimino el código irrelevante relacionado con él)

 private final class FetchFriendsLists extends AsyncTask<Long, Integer, Void> { protected final Void doInBackground(final Long... params) { if (params[0] != Long.valueOf(-1)) { [...] twitterAPI.fetchUserFriendsList(); publishProgress(1, -1); } if (params[1] == Long.valueOf(0)) { [...] facebookAPI.fetchFriendsList(); publishProgress(-1, 0); } return null; } protected final void onProgressUpdate(Integer... flags) { super.onProgressUpdate(flags); if (flags[0] != -1) twitterAPI.asyncSaveFacebookFriendsList(); if (flags[1] == 0) facebookAPI.asyncSaveFacebookFriendsList(); } } 

Como puedes ver, comienzo los pasos 2 y 3 en onPublishProgress() que se ejecuta en el subproceso principal de la interfaz de usuario. Brefore fue en el método doInBackground() : el problema se produce en ambos casos!

[EDIT] Después de otra prueba, parecería que cualquier tipo de código se ejecuta en realidad dos veces. Creé un método simple llamado prueba en el que en la impresión de un contador. ¡El contador incremente dos veces tan bien!

¿Por qué utiliza onProgressUpdate? ¿?

OnProgressUpdate (Progreso …), […]. Este método se utiliza para mostrar cualquier forma de progreso en la interfaz de usuario mientras el cálculo de fondo sigue ejecutándose. Por ejemplo, se puede utilizar para animar una barra de progreso o mostrar registros en un campo de texto.

Esto se utiliza no al final de la petición, pero cuando el progreso aumentó.
Lee esto:
http://developer.android.com/reference/android/os/AsyncTask.html

Usted necesita usar:

  protected void onPostExecute(Long result) { 
  • Android: ejecuta código en intervalos regulares
  • Cuando está fuera del hilo principal, ¿cómo puedo obtener algún código para ejecutarse en el hilo principal lo más rápido posible?
  • Java / Android espera hasta que haya terminado un hilo antes de ejecutar un nuevo método
  • Espere a que los hilos se completen antes de continuar
  • Los subprocesos predeterminados de Android y su uso
  • ¿Cómo ejecutar la solicitud web en su propio hilo?
  • ¿Cómo puedo ejecutar código en un hilo de fondo en Android?
  • Android: forma correcta de pasar un mensaje de hilo de fondo a hilo de interfaz de usuario?
  • ¿Es un error o una característica? En algunos casos es posible acceder al subproceso de interfaz de usuario de una tarea que no se ejecuta en el subproceso de interfaz de usuario
  • Nuevo hilo varias veces
  • ¿Algún consejo sobre cómo acelerar esto en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.