2015-07-17 8 views
5

Ho un'app per Android, che mostra una "schermata iniziale" per 3 secondi. Successivamente, viene caricato MainActivity.Schermo Android Splash-Screen durante il caricamento

Sfortunatamente il MainActivity richiede ulteriori ~ 4 secondi per il caricamento. Al primo avvio ancora più a lungo. Tuttavia, quando l'app viene caricata, tutto procede liscio.

Ora, come posso ottenerlo, che l'attività MainActivity viene caricata durante la visualizzazione della schermata iniziale? Dovrebbe solo visualizzare un'immagine fino a quando l'intera cosa non viene caricata completamente. Ho letto su Async-Task, ma non sono sicuro di dove metterlo e come usarlo correttamente. Qualcuno può aiutarmi per favore?

SplashScreen.java

public class SplashScreen extends Activity { 
    private static int SPLASH_TIME_OUT = 3000; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_startup); 

     new Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       Intent i = new Intent(SplashScreen.this, MainActivity.class); 
       startActivity(i); 
       finish(); 
      } 
     }, SPLASH_TIME_OUT); 
    } 
} 

MainActivity.java

public class MainActivity extends Activity implements OnClickListener, MediaController.MediaPlayerControl { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     //Some heavy processing 
     //starting services 
     //starting Google Text to Speech 
     //and so on... 

    } 

} 
+2

Una soluzione potrebbe essere quella di utilizzare solo 'MainActivity', visualizzando inizialmente il layout della schermata iniziale, in seguito nascondendolo/rimuovendolo (tramite' Handler.postDelayed() ', ad esempio) per mostrare il layout dell'attività corrente. – Mikhail

+0

Questo nuovo suggerimento dagli sviluppatori Android potrebbe essere utile: https://plus.google.com/+AndroidDevelopers/posts/Z1Wwainpjhd –

+0

Hai già cercato su Google? Ci sono un sacco di esempi per te. Controlla questo http: // www. androidhive.info/2013/07/how-to-implement-android-splash-screen-2/ – Soham

risposta

6

Se non ci sono vincoli specifici tempo la schermata iniziale dovrebbe essere mostrato, si potrebbe utilizzare il AsyncTask nel seguente modo:

public class SplashScreen extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_startup); 
     startHeavyProcessing(); 

    } 

    private void startHeavyProcessing(){ 
     new LongOperation().execute(""); 
    } 

    private class LongOperation extends AsyncTask<String, Void, String> { 

     @Override 
     protected String doInBackground(String... params) { 
      //some heavy processing resulting in a Data String 
      for (int i = 0; i < 5; i++) { 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        Thread.interrupted(); 
       } 
      } 
      return "whatever result you have"; 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      Intent i = new Intent(SplashScreen.this, MainActivity.class); 
      i.putExtra("data", result); 
      startActivity(i); 
      finish(); 
     } 

     @Override 
     protected void onPreExecute() {} 

     @Override 
     protected void onProgressUpdate(Void... values) {} 
    } 
} 

Se i dati risultanti, se di altra natura che una stringa si potrebbe mettere un oggetto Parcelable come un extra per la vostra attività. In onCreate è possibile recuperare i dati con:

getIntent().getExtras.getString('data');

+1

Grazie! Questa è un'ottima soluzione! – HorstB

0

il codice splash screen funziona bene, ma quando si chiama prossima attività poi nel onCreate() utilizzare per il vostro AsyncTask pesante attività ...

0

ne dite, nell'interesse della semplicità, si combinano l'attività di apertura con la tua attività principale? In questo modo puoi ottenere il meglio da entrambi i mondi, vale a dire uno splash screen mentre i tuoi dati si stanno preparando per la prima volta e un avvio rapido quando è stato preparato in precedenza. Rendendo l'utente attesa per nulla non è davvero una buona forma ...

Qualcosa di simile:

public class MainActivity extends Activity implements OnClickListener, MediaController.MediaPlayerControl { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Initially shows splash screen, the main UI is not visible 
     setContentView(R.layout.activity_main); 

     // Start an async task to prepare the data. When it finishes, in 
     // onPostExecute() get it to call back dataReady() 
     new PrepareDataAsyncTask(this).execute(); 

    } 

    public void dataReady() { 
     // Hide splash screen 
     // Show real UI 
    } 

} 
14

Non dovrebbe essere la creazione di un nuovo thread all'avvio, invece è necessario creare una vista che non ha bisogno di attendere il caricamento delle risorse, come descritto in questo articolo: Splash Screens the Right Way.

Come indicato in questo articolo, è necessario creare un layer-list drawable invece di un file XML layout:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 

    <!-- Fill the background with a solid color --> 
    <item 
     android:drawable="@color/gray"/> 
    <item> 

    <!-- Place your bitmap in the center --> 
    <bitmap 
     android:gravity="center" 
     android:src="@mipmap/ic_launcher"/> 
    </item> 

</layer-list> 

quindi creare un tema utilizzando il file drawable come sfondo. Io uso l'attributo background anziché l'attributo windowBackground come suggerito nell'articolo, perché lo background prende in considerazione lo stato e le barre di navigazione, centrando meglio il drawable.Ho anche impostare windowAnimationStyle a null in modo che la schermata iniziale non animare la transizione alla MainActivity:

<resources> 

    <!-- Base application theme --> 
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> 
     <!-- Customize your theme here. --> 
    </style> 

    <!-- Splash Screen theme --> 
    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar"> 
     <item name="android:background">@drawable/background_splash</item> 
     <item name="android:windowAnimationStyle">@null</item> 
    </style> 

</resources> 

quindi dichiarare il tema nel manifesto per la vostra SplashActivity:

<activity android:name=".SplashActivity" 
    android:theme="@style/SplashTheme"> 
    <intent-filter> 
     <action android:name="android.intent.action.MAIN" /> 

     <category android:name="android.intent.category.LAUNCHER" /> 
    </intent-filter> 
</activity> 

E finalmente tutto quello che hanno SplashActivity avvia il tuo MainActivity e la schermata iniziale verrà visualizzata solo per il tempo necessario alla configurazione dell'app:

public class SplashActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     Intent intent = new Intent(this, MainActivity.class); 
     startActivity(intent); 
     finish(); 
    } 
} 
+0

La migliore risposta, grazie! –

+0

Questa dovrebbe essere la risposta accettata. In realtà risponde alla domanda dell'OP. – wsgeorge

+0

Un buon approccio, ma possiamo visualizzare una barra di avanzamento nella schermata iniziale creata in questo modo? – Journey