Autore Topic: Creare un NetworkManager: AsyncTask, Thread...?  (Letto 743 volte)

Offline spiaggefredde

  • Nuovo arrivato
  • *
  • Post: 1
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire S
  • Sistema operativo:
    Windows 7, Ubuntu 12.04
Creare un NetworkManager: AsyncTask, Thread...?
« il: 12 Maggio 2012, 16:57:17 CEST »
0
Salve a tutti!
Sto sviluppando un'applicazione prevede la connessione ad un server per svolgere una serie di operazioni (dalle semplici login e registrazione fino a operazioni più complesse, ma sempre over HTTP con dati in JSON).
Ho implementato un controller che include una classe NetworkManager: essa include i vari metodi di connessione al server (sendLoginRequest, sendRegistrationRequest...) che si occupano di incapsulare i dati in un oggetto JSON, più un metodo di servizio sendMessage utilizzato da tutti i sopracitati metodi che si occupa di effettuare l'effettiva connessione al server e ritornare il relativo JSON object di risposta.

Siccome le connessioni alla rete sono bloccanti e possono freezare l'UI, ho pensato di includere nel NetworkManager un AsyncTask innestato che si occupa di effettuare le operazioni in un background thread. Ho spostato quindi il codice della sendMessage all'interno del metodo doInBackground(), mentre nel corpo della sendMessage ho eseguito l'execute() dell'AsyncTask.

Il problema dell'utilizzo di un AsyncTask però, risiede nel fatto che sebbene le chiamate debbano essere eseguite in un thread diverso dal Main Thread, le mie operazioni sono tipicamente "sincrone" per la natura di HTTP: ho bisogno di attendere un risultato prima di effettuare una qualsiasi operazione che lo debba utilizzare. Non essendo prevedibile l'ordine di  esecuzione dei due thread, spesso il risultato non è ancora disponibile, generando delle NullPointerException laddove il dato viene consumato dopo la creazione dell'AsyncTask.

Il motivo per cui vorrei che l'AsyncTask fosse "general purpose" risiede nel fatto che i metodi di richieste al server possono ritornare tipi di dato diversi (es: la loginRequest ritorna un intero di controllo, mentre la getProfileRequest ritorna un oggetto JSON comprendente al suo interno i dati relativi al profilo dell'utente) e la onPostExecute() deve quindi eseguire operazioni diverse a seconda del dato ritornato dalla richiesta al server.

La mia domanda quindi è: esiste una soluzione condivisa (nel senso utilizzata per la maggiore) con la quale realizzare un network manager che sia thread-safe e che mantenga il codice di connessione il più separato possibile dalle activity (per intenderci: senza istanziare Thread o AsyncTask nelle activity ma solo eseguire i metodi tipo sendLoginRequest , il cui codice poi si smazzerà la gestione della concorrenza)?
Preciso che non voglio necessariamente che la soluzione preveda l'impiego di un'AsyncTask, quanto che....esista una soluzione od un pattern  che mi permetta di riciclare più codice possibile!

Grazie ;-)
« Ultima modifica: 12 Maggio 2012, 17:09:17 CEST da spiaggefredde »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Creare un NetworkManager: AsyncTask, Thread...?
« Risposta #1 il: 13 Maggio 2012, 09:18:32 CEST »
0
Se ho compreso bene la problematica, il modo a mio parere più corretto per gestire queste operazioni è renderle tutte asincrone. Per esempio se devi fare un login, dal main thread richiami una funzione sendLoginRequest che crea un asynctask per la connessione di login, e a sua volta l'asynctask non appena ha finito invia un messaggio al main thread.

Tutto è asincrono, nel senso che tu avvii il login richiamando una funzione ed aspetti che ritorni un messaggio di conferma (l'uso dei messaggi rende tutto implicitamente thread-safe).

NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline qato

  • Nuovo arrivato
  • *
  • Post: 46
  • Respect: +3
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus 5
Re:Creare un NetworkManager: AsyncTask, Thread...?
« Risposta #2 il: 13 Maggio 2012, 10:47:47 CEST »
0
Non credo di aver compreso bene quale sia il problema ed il risultato atteso
Credo che tu abbia delle micro_funzioni da eseguire in sequenza per soddisfare una macro_funzione, e queste micro_funzioni necessitano di un thread separato dalla UI, corretto?
Se così puoi implementare un pattern Command dove, ogni command implementa una micro_funzione, e la macro_funzione è una sequenza di micro_funzioni gestite dall'AsyncTask nel metodo doInBackground
Qualcosa di simile
Codice: [Seleziona]
     protected Integer doInBackground(MyCommand... cmds) {
         int count = cmds.length;
         int result=0;
         try {
           for (int i = 0; i < count; i++) {
               result += cmds[i].execute();
           }
         } catch (Exception e) { result=-1; }
         return result;
     }