Android: modello per il controllo dei requisiti all'avvio?

7

L'attività di avvio della mia app verifica una serie di requisiti come se il GPS è abilitato, c'è una connessione di rete, l'app ha i privilegi di amministratore del dispositivo, ecc. Alcuni di questi controlli visualizzano le finestre di dialogo o portano l'utente a un'altra attività per risolvere i requisiti insoddisfatti . Sto cercando un modo per farlo facile da estendere con più requisiti e facile da leggere e capire per gli altri.

La mia soluzione originale era di eseguire i controlli in sequenza, ognuno nel suo metodo, con ciascun metodo che prendeva azione correttiva o chiamava il metodo successivo nella sequenza. La sequenza è iniziata in onResume() , quindi al ritorno da un'altra attività riprende con il primo controllo che non passa. Questo è diventato veloce perché alcuni requisiti sono condizionali. Ad esempio, su Lollipop controlla se l'app è il proprietario del dispositivo e se potrebbe essere in grado di diventare il proprietario del dispositivo. Se possibile, indica all'utente di eseguire il comando adb shell appropriato. Naturalmente, l'intera sequenza di controlli viene saltata su KitKat. Quindi la catena di metodi è in realtà più simile a una treccia intrecciata. È difficile rintracciarne la logica o verificare che ogni passo alla fine chiami il prossimo in tutte le possibili condizioni. Sono riluttante a apportarvi modifiche e l'ho appena scritto un paio di settimane fa.

La mia altra idea era di numerare i passi (o associarli agli elementi di un enum ) e passare il passaggio completato da ultimo tra le istanze di attività. Ma prevedo che anche questo sia complicato.

Come struttureresti questo?

    
posta Kevin Krumwiede 25.06.2015 - 06:07
fonte

2 risposte

1

Non sono sicuro che questa sia la soluzione migliore, ma questo è ciò che ho finito per fare:

Ho inserito tutti i miei controlli dei requisiti nella onResume() di un frammento senza testa e l'ho aggiunto alla mia attività in onCreate(...) . Se uno qualsiasi dei requisiti non viene soddisfatto, il frammento senza testa mostra frammenti di dialogo che spiegano cosa deve fare l'utente prima di portarlo alle impostazioni di sistema. Quando tutti i requisiti sono soddisfatti, chiama un metodo sull'attività. (Potrei cambiarlo per trasmettere un evento per separare completamente il frammento dall'attività.)

Questo non rende la logica della sequenza di controlli meno disordinata, ma almeno sposta tutto il codice fuori dall'attività, rendendo entrambe le parti più facili da navigare e capire.

Modifica: sei mesi dopo, ho rifattorizzato la soluzione di cui sopra in qualcosa di molto più OO.

public interface Requirement {
    /**
     * Checks a system requirement and calls {@link
     * StartActivity#nextRequirement()} when it's satisfied.
     *
     * @param activity the current activity
     */
    void check(final StartActivity activity);
}

A List<Requirement> viene iniettato nell'attività utilizzando Dagger2. Posso facilmente aggiungere altri requisiti e il loro ordine è facile da vedere e modificare nel modulo di Dagger.

@Inject List<Requirement> mRequirements;
private Iterator<Requirement> mRequirementsIterator;

void checkRequirements() {
    mRequirementsIterator = mRequirements.iterator();
    nextRequirement();
}

void nextRequirement() {
    if(mRequirementsIterator.hasNext()) {
        mRequirementsIterator.next().check(this);
    }
    else {
        onRequirementsSatisfied();
    }
}

chiamo checkRequirements() da onResume() . Qualsiasi frammento di finestra di dialogo visualizzato da Requirement si disattiva nel proprio onPause() , poiché verranno visualizzati di nuovo se il requisito non è ancora soddisfatto al successivo riavvio dell'attività.

    
risposta data 12.08.2015 - 21:33
fonte
0

Abbiamo usato un unico metodo che non ha fatto altro che determinare quali cose dovevano essere impostate e restituire un valore che è stato passato in un secondo metodo che era in realtà solo una gigantesca affermazione dell'interruttore. Ogni elemento (come isGpsAvailable) ha il proprio metodo che è stato inserito nel caso appropriato a seconda dell'ambiente.

    
risposta data 28.08.2015 - 21:49
fonte

Leggi altre domande sui tag