2010-04-06 15 views
5

Ho un compito comune che faccio con alcune attività: scaricare i dati e visualizzarli. Ho scaricato la parte download pat; è, ovviamente, un po 'complicato a causa della possibilità che l'utente cambi l'orientamento o annulli l'attività prima che il download sia completato, ma il codice è lì. C'è abbastanza codice per gestire questi casi in modo tale che non voglio doverlo copiare/incollare su ogni attività che ho, quindi ho pensato di creare una sottoclasse di attività astratta in modo tale che gestisca un singolo download in background che poi avvia un metodo che riempie la pagina di dati.Esiste un modello di progettazione per ridurre la duplicazione del codice durante la sottoclasse di attività in Android?

Tutto questo funziona. Il problema è che, a causa dell'ereditarietà singola, sono costretto a ricreare esattamente la stessa classe per qualsiasi altro tipo di attività: ad esempio, utilizzo Activity, ListActivity e MapActivity. Utilizzare la stessa tecnica per tutti e tre richiede tre classi duplicate, tranne che ciascuna estende un'attività diversa.

Esiste un modello di progettazione che può ridurre la duplicazione del codice? Così com'è, ho già salvato molte duplicazioni, ma mi fa male vedere lo stesso codice in tre classi solo in modo che ciascuna sottoclasse un diverso tipo di attività.

Edit: Poiché sembra che ho bisogno di essere un po 'più specifico ...

Supponiamo che sto cercando di risolvere il problema di un AsyncTask background Scaricate durante i cambi di orientamento. La soluzione che ho adesso è usare i callback; c'è il download manager che ho che avvia questi download, e poi ho l'attività allegare un callback ad esso. Quando l'orientamento cambia, l'attività viene distrutta e quindi ricreata; durante questo processo, scollego il callback della vecchia attività, quindi allego un nuovo callback dalla nuova attività in seguito.

Le modifiche di orientamento sono un problema comune e in più attività avvio l'attività con una vista di avanzamento durante il caricamento dei dati. Quello che sto cercando di risolvere non è il dover reimplementare questa logica di gestione dell'orientamento dieci volte; la mia soluzione iniziale era di sottoclasse Attività, ma poi ho avuto il problema sopra.

risposta

3

Prefer composition over inheritance. Qualunque cosa sia comune, delegare ad alcune classi che possono essere membri di Activity, ListActivity e MapActivity.

+0

Capisco perfettamente questo concetto, ma fare la composizione in questo caso significherebbe solo la duplicazione del codice tanto quanto semplicemente implementandola in ogni classe. Ogni classe dovrebbe implementare onCreate(), onRetainNonConfigurationInstance(), onResume(), onPause(), onDestroy() e chiamare il delegato. Preferirei non dover pensare a questo aspetto dell'implementazione per ogni attività che scrivo. Potrei essere convinto del contrario, ma in questo caso la composizione produce altrettante duplicazioni, a meno che non manchi qualcosa. –

+0

Ick. Ciò suggerisce che le attività di Android sono troppo grandi e probabilmente non ne hai il controllo. Suppongo che potresti scrivere un DelegatingActivity con quelle funzioni (e assignDelegate() o somesuch) già scritte e ereditate da questo. Come l'hai descritto finora, questo non ha molto vantaggio su una semplice interclasse di attività, ma potrebbe ripagare la strada. –

+0

Il modo in cui le attività funzionano è che hanno metodi diversi chiamati in stati diversi (ad esempio "onCreate()" e "onDestroy()"). Quando implementi la tua attività, sottolisti e estendi questi metodi per definire il comportamento. Il tuo post mi ha dato un'idea, che è quella di creare ancora più sottoclassi di varie attività, ma di avere ogni implementare un delegato all'interno di esso; in questo modo non sto implementando lo stesso codice ogni volta. Tuttavia, speravo in una soluzione leggermente meno caotica. –

0

Il problema è che si sta mescolando la vista e la logica del programma. Un thread in background come AsyncTask verrà eseguito finché l'applicazione non viene eliminata dal sistema. Si può eseguire il download di tutto nel task asincrono e quindi salvarlo da qualche parte sulla SD-Card per recuperarlo da lì se è pronto.

È possibile creare una sottoclasse di application class per contenere un riferimento all'attività o un gestore per comunicare con la classe da ogni attività.

Se questa non è una soluzione al tuo problema, potresti forse chiarire un po 'la domanda. Sarebbe utile sapere cosa stai facendo nei metodi onCreate ....

+0

Penso che tu abbia una visione ristretta di ciò che ho già impostato. :) Ho scritto una libreria per il download in background tramite AsyncTask, tuttavia una tale libreria non può tenere conto di problemi come la distruzione/ricreazione delle attività tramite i cambiamenti di orientamento. Quando l'orientamento cambia, devo essere in grado di ricollegare l'attività al download già in corso (nel mio caso, impostando una nuova richiamata). Il codice di cui sto parlando per ridurre la duplicazione è questo codice; ogni attività deve gestire i cambiamenti di orientamento e dal momento che è lo stesso codice tra ciascuno, voglio solo riutilizzarlo. –

+0

Io ancora non capisco cosa si sta facendo in tutte le onResume OnDestroy ecc attività, forse si dovrebbe dare alcuni esempi di codice – Janusz

0

Non ho utilizzato MapActivity, ma ho risolto questo problema non utilizzando ListActivity e fornendo la funzionalità da solo in Activity. Non c'è davvero tanto in ListActivity se si guarda: http://google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/app/ListActivity.java Implementare la funzionalità da soli si ottiene più personalizzazione e più spazio per crescere.

+0

ho pensato la vostra soluzione, ma secondo la documentazione MapActivity non può essere ignorato in modo: "A MapView . può essere costruito solo (o gonfiato) da un MapActivity Questo è perché dipende fili che accedono alla rete e file system in background,. queste filettature vanno shepherded dalla gestione del ciclo di vita in MapActivity" (Http://code.google.com/android/add-ons/google-apis/reference/com/google/android/maps/MapView.html) –

+0

corect, ho affrontato lo stesso problema e anzi, invece di ListAcivity ho usato my OwnActivity con alcune implementazioni ma con MapActivity tutto ciò che potevo fare era copiare-incollare. la soluzione alla fine ho usato, non perché è bella e pulita, ma perché è la centralizzazione del codice in un unico luogo è quello di utilizzare un'interfaccia per le mie attività di base ha bisogno (nel tuo caso onDownloadFinish, onDetachListener, onAttachListener ecc ...) e di avere una classe delegante implementare questi metodi, allora ogni attività che ha bisogno che il comportamento sarà anche implementare l'interfaccia e delegare tutte le chiamate verso quell'oggetto ... – codeScriber

0

Un modo per avere una classe di supporto con metodi statici a cui passare le attività e fare il lavoro comune lì anziché in ogni attività?

+0

Attualmente ho qualcosa di simile a questa configurazione, se per la natura di quello che sto facendo che deve essere un metodi istanziati non statici. Tuttavia, questa soluzione significa che è necessario riscrivere lo stesso codice in ogni attività che desidera utilizzare questa funzionalità oppure è necessario suddividere in sottoclassi ogni tipo di attività per ridurre la duplicazione del codice. –

Problemi correlati