Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load an activity in the background before displaying it

Tags:

android

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!

like image 652
romamnmlst Avatar asked Oct 23 '12 18:10

romamnmlst


People also ask

What is background activity in Android?

Definition of background work. An app is running in the background when both the following conditions are satisfied: None of the app's activities are currently visible to the user. The app isn't running any foreground services that started while an activity from the app was visible to the user.

What is restrict background activity?

Android 10 (API level 29) and higher place restrictions on when apps can start activities when the app is running in the background. These restrictions help minimize interruptions for the user and keep the user more in control of what's shown on their screen.

How do I know if an app is running in the background Android?

You can detect currently foreground/background application with ActivityManager. getRunningAppProcesses() which returns a list of RunningAppProcessInfo records. To determine if your application is on the foreground check RunningAppProcessInfo.


2 Answers

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:

setContentView(R.layout.splash_screen);

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>> {

    @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
    }
}

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.

like image 80
hiBrianLee Avatar answered Oct 06 '22 11:10

hiBrianLee


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.

like image 25
Marcin S. Avatar answered Oct 06 '22 09:10

Marcin S.