2012-10-23 10 views
7

È possibile caricare una nuova attività in background prima di passare alla visualizzazione di quella attività?Carica un'attività in background prima di visualizzarla

Ad esempio, mi piacerebbe avere un'attività su schermo che viene chiamata e visualizza una schermata iniziale. Mentre viene visualizzata questa schermata iniziale, viene caricata l'attività successiva e al termine del caricamento (al termine di onCreate()), l'attività della schermata iniziale termina e viene visualizzata la nuova attività.

Conosco un'altra opzione per visualizzare la schermata iniziale nella nuova attività e utilizzare un'attività asincrona per caricare tutti i dati prima di rimuovere l'immagine splash ... ma sono bloccato anche su tale approccio. L'attività deve innanzitutto caricare una discreta quantità di dati e quindi deve aggiungere in modo dinamico elementi GUI basati su tali dati. Una volta che la GUI è completamente caricata, allora voglio rimuovere la schermata iniziale. Il problema è che non riesco a toccare il thread dell'interfaccia utente da doInBackground(). Come posso creare la mia attività dietro una schermata iniziale, se non riesco ad aggiornare l'interfaccia utente da doInBackground? So che onProgressUpdate() può accedere al thread dell'interfaccia utente, ma non riesco a capire come implementarlo.

Qualche idea? Grazie!

risposta

5

Dato che non si dispone di un esempio del codice, non sono sicuro del tipo di dati che si sta caricando e di come si configura dinamicamente l'interfaccia utente in base ai dati, ma cercherò di rispondere quanto Io posso. Di conseguenza, la risposta potrebbe sembrare un po 'generica.

Innanzitutto, definire 2 file di layout xml: uno per la schermata iniziale e uno per l'attività "principale". Così si ritroverà con /res/layout/splash_screen.xml e /res/layout/main.xml

Nella tua onCreate(), caricare il layout splash_screen:

setContentView(R.layout.splash_screen); 

Nella tua asincrona compito, caricherete tutti i dati che dovete fare e salverete tutti i dati in una sorta di struttura dati. Userò una LinkedList di String per esempio.

private class MyTask extends AsyncTask<Uri, Integer, List<String>> { 

    @Override 
    protected List<String> doInBackground(Uri... params) { 
     List<String> myList = new LinkedList<String>(); 
     // load up the list with data you are trying to get 
     myList.add("foo"); 
     myList.add("bar"); 
     // whatever you return here will be passed in as a parameter to the onPostExecute() 
     return myList; 
    } 

    @Override 
    protected void onPostExecute(List<String> result) { 
     setContentView(R.layout.main2); 
     // set layout elements with data that from the result 
     TextView myTextView = (TextView) findViewById(R.id.some_label); 
     myTextView.setText(result.get(0)); 
     // or just call some function you defined in your activity instead 
    } 
} 

Quindi, fondamentalmente, hanno 2 file di layout diverso e utilizzare il layout splash_screen, e utilizzare l'attività asincrona il carico dei dati e salvarlo in qualche struttura dati si definisce, e l'uso che la struttura dei dati per caricare i elementi dell'interfaccia utente in onPostExecute() dopo aver usato setContentView() per tornare al layout principale.

Una nota speciale: Con il codice sopra riportato, mostrerà di nuovo la schermata iniziale e ricaricherà di nuovo tutti i dati se si ruota lo schermo. Se si desidera evitare ciò, è possibile utilizzare onSaveInstanceState() e salvare i dati desiderati in outBundle e leggere nuovamente tali dati nel pacchetto savedInstanceState di onCreate e caricare gli elementi dell'interfaccia utente di backup. Ciò richiederà un thread separato (o puoi solo cercare su di esso) se volessi saperne di più sulla gestione della rotazione.

+0

Mi dispiace di non poter fornire alcun codice, in quanto ho firmato una NDA che mi impedisce di condividere il codice. Posso parlare in generale comunque. In pratica sto caricando un xml a seconda di una condizione, e quel file xml mi dice quali immagini devo mostrare, così come le informazioni che sono legate a quell'immagine. Passo e creo dinamicamente le immagini dall'elenco delle immagini restituite e le aggiungo a una vista. Ci vogliono 2-3 secondi prima che compaia tutto sullo schermo (ci sono molte immagini), quindi voglio mostrare uno splash fino a quando tutto è caricato e pronto per essere interagito con. – romamnmlst

+0

In questo caso, penso che si possa analizzare il file XML nella funzione doInBackground() sopra, creare il ImageView e impostare l'origine dell'immagine e restituire un elenco di ImageView dalla funzione doInBackground(). La funzione onPostExecute() prenderà l'elenco di ImageViews e le aggiungerà alla gerarchia della vista dopo setContentView(). Tutto ciò che fai in onPostExecute() viene eseguito nel thread principale in modo da poter modificare gli elementi dell'interfaccia utente da qui. – hiBrianLee

+0

Eccellente, darò uno scatto e vedrò come funziona. Grazie! (Potrebbe volerci un po ', ma se funziona sarò sicuro di tornare e contrassegnare la tua risposta come accettata) – romamnmlst

1

Una delle soluzioni per risolvere il problema a cui posso pensare è l'utilizzo di un'attività per la visualizzazione della schermata iniziale e del contenuto. Poiché è possibile chiamare il metodo setContentView() in qualsiasi momento (non solo nel metodo onCreate()), basta definire tutte le viste desiderate in file XML separati e passare l'id pertinente a setContentView() quando è il momento di passare.

Si può anche utilizzare un layout con le proprie viste e schermate iniziali e nascondere/mostrare gli attributi. Quando i tuoi dati caricano setVisibility sulla tua schermata iniziale su Visible mentre la tua vista root rimane invisibile. Quando finisci di caricare, fai il contrario.

Problemi correlati