Load an activity in the background before displaying it

懵懂的女人 提交于 2019-12-04 19:33:31


Is it possible to load a new activity in the background before switching the view to that activity?

For example, I would like to have a slash screen activity that gets called and displays a splash screen. While this splash screen is displayed, the next activity is loaded, and when it is done loading (when it's onCreate() is finished) then the splash screen activity ends, and the new activity is displayed.

I know another option would be to display the splash screen in the new activity, and use async task to load all the data before removing the splash image... but I am stuck on that approach as well. The activity first has to load a fair amount of data, and then it has to dynamically add GUI elements based on that data. Once the GUI is fully loaded, I then want to remove the splash screen. The problem is that I cannot touch the UI thread from doInBackground(). How do I create my activity behind a splash screen, if I cannot update the UI from doInBackground? I know that onProgressUpdate() can access the UI thread, but I can't figure out how to implement it.

Any ideas? Thank you!


Since you don't have an example of your code, I am not sure what kind of data you are loading and how you are dynamically configuring the UI based on the data, but I'll try to answer as much as I can. As a result, the answer may sound a little generic.

First, define 2 layout xml files - one for the splash screen and one for your "main" activity. So you'll end up with /res/layout/splash_screen.xml and /res/layout/main.xml

In your onCreate(), load the splash_screen layout:


In your async task, you will load up whatever data you need to do, and you will save all that data in some sort of data structure. I'm gonna use a LinkedList of String for example's sake.

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

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

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

So basically, have 2 different layout file and use the splash_screen layout, and use the async task the load the data and save it in some data structure you define, and use that data structure to load your UI elements in onPostExecute() after using setContentView() to change back to your main layout.

One special note: With the above code, it will show the splash screen again and reload all the data again if you rotate the screen. If you want to avoid that, you can use the onSaveInstanceState() and save whatever data you want in the outBundle and read that data back in onCreate's savedInstanceState bundle and load the UI elements back up. This will require a separate thread (or you can just search about it) if you wanted to know more about handling rotation.


One of the solution to solve your problem I can think about is to use one activity for displaying the splash screen and your content. Since you can call setContentView() method at any time (not only in onCreate() method) just define all the views you want in separate XML files and pass the relevant id to setContentView() when it's time to switch.

You could also use one layout with your views and splash screens and hide / unhide attributes. When your data is loading setVisibility to your splash screen to Visible while your root view remain unvisible. When finish loading - do in the opposite way.