Android Tutorial, Part 4: Intents and Introduction to Threads

Hi all! This is the fourth part of this tutorial series to teach newbies to develop apps for android using its native language Java and the official android IDE Android Studio. You are free to use and share, and spread this tutorial with or without permission as long as you would link and give attribution to the source material.

If you haven’t seen the previous lessons, please read that first
In the previous lessons, we’ve defined our simple Splash Screen through the XML Layout file. Now, I will teach you about Intents.

Based on the Java Docs on the Android source code: An Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed.

This is a feature inherently unique on Android, as you may have probably noticed, Android Apps can communicate with each other, an Activity on your app can start another Activity (not limited to your app) as long as the correct flags are set. For example, a share button on your app can send an Intent with the ACTION_SEND action type. This means that Android will look for apps with Activity that accepts the ACTION_SEND flag and will start that accordingly.

As I’ve explained earlier, Activities are equivalent to 1 screen of our application, how can we move from our current Activity to the next? This can be done through Intents.

Let’s try it, create another activity first then by right-clicking on our package.



Select Empty Activity and name it DashboardActivity
Android Studio will then prompt you if you want to add the newly added files to git, make sure both the java file and xml file are selected, then click OK.



Let’s add this code inside our SplashScreenActivity’s onCreate() below the setContentView
Intent intent = new Intent(this, DashboardActivity.class);
startActivity(intent);

It should look similar to this:

Code:
public class SplashScreenActivity extends AppCompatActivity {

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

        Intent intent = new Intent(this, DashboardActivity.class);
        startActivity(intent);
    }
}

Let’s try to run the app and see what happens. It looks like we’re going straight to the DashboardActivity but we’re not. Try to press the ‘back’ button once and you’ll get back to the SplashScreenActivity. Why does this happen? 1.) We’re not setting a delay before we start DashboardActivity and 2.) We’re not destroying the SplashScreenActivity after we start DashboardActivity.

Let’s create a new Handler to delay our execution of our startActivity, our code should look like this:

Code:
/* New Handler to start the Dashboard
 * and close this SplashScreen after some seconds.*/
new Handler().postDelayed(new Runnable(){
    @Override
    public void run() {
        /* Create an Intent that will start the Dashboard-Activity. */
        Intent intent = new Intent(SplashScreenActivity.this, DashboardActivity.class);
        startActivity(intent);
        finish();
    }
}, 2000);

Now, you might be wondering how did I know of Handler and what is a Handler. Let’s take care of your first question, please click this link: http://bfy.tw/4qJu

What is a Handler?
let’s look at the source code:
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

Scheduling messages is accomplished with the #post, #postAtTime(Runnable, long), #postDelayed, #sendEmptyMessage, #sendMessage, #sendMessageAtTime, and #sendMessageDelayed methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's #handleMessage method (requiring that you implement a subclass of Handler).

When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.
When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. The given Runnable or Message will then be scheduled in the Handler's message queue and processed when appropriate.

Summary: The Handler will create a new thread and we can supply a runnable to run at that new thread. We can delay the runnable’s execution by using the postDelayed method of the Handler and supplying a runnable in it. Thus our code:

Code:
/* New Handler to start the Dashboard
 * and close this SplashScreen after some seconds.*/
new Handler().postDelayed(new Runnable(){
    @Override
    public void run() {
        /* Create an Intent that will start the Menu-Activity. */
        Intent intent = new Intent(SplashScreenActivity.this, DashboardActivity.class);
        startActivity(intent);
        finish();
    }
}, 2000);

I’m going to explain the code part by part.
Code:
new Handler()

Notice the “new” key word? This means that we are creating / instantiating a new instance of the Handler class, this means that we can now access non-static methods inside the Handler class.
Code:
postDelayed(Runnable, int)

As you see, postDelayed accepts two parameters, a Runnable and an integer. It will run the supplied Runnable exactly after the supplied integer in milliseconds has passed.

In our case we did this as a shorthand syntax:
Code:
new Handler().postDelayed(new Runnable(){
    @Override
    public void run() {
        /* Create an Intent that will start the Dashboard-Activity. */
        Intent intent = new Intent(SplashScreenActivity.this, DashboardActivity.class);
        startActivity(intent);
        finish();
    }
}, 2000);

If you are getting confused of what it does, this is the longer more verbose version:
Code:
Handler handler = new Handler();
Runnable runnable = new Runnable(){
    @Override
    public void run() {
        /* Create an Intent that will start the Dashboard-Activity. */
        Intent intent = new Intent(SplashScreenActivity.this, DashboardActivity.class);
        startActivity(intent);
        finish();
    }
};
int delayInMillis = 2000; // 2 seconds
handler.postDelayed(runnable, delayInMillis);

Let’s move on to the intent:
Code:
Intent intent = new Intent(SplashScreenActivity.this, DashboardActivity.class);
startActivity(intent);
finish();

Here, we are creating a new instance of Intent, supplying it will the current Activity:
Code:
SplashScreenActivity.this

Then the class of the Activity we’re starting:
Code:
DashboardActivity.class

We then proceed to start this activity using the Intent we just created:
Code:
Intent intent = new Intent(SplashScreenActivity.this, DashboardActivity.class);
startActivity(intent);

Then finish the current Activity using the finish() method:
Code:
Intent intent = new Intent(SplashScreenActivity.this, DashboardActivity.class);
startActivity(intent);
finish();

We combine what we’ve learned here altogether and we’ll have something similar to this:
Code:
public class SplashScreenActivity extends AppCompatActivity {

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

        /* New Handler to start the Dashboard
         * and close this SplashScreen after some seconds.*/
        Handler handler = new Handler();
        Runnable runnable = new Runnable(){
            @Override
            public void run() {
                /* Create an Intent that will start the Dashboard-Activity. */
                Intent intent = new Intent(SplashScreenActivity.this, DashboardActivity.class);
                startActivity(intent);
                finish();
            }
        };
        int delayInMillis = 2000; // 2 seconds
        handler.postDelayed(runnable, delayInMillis);
    }
}

Commit everything and push to our current branch. You know how to do it right? C’mon, I know you can.

Congratulations! You have just learned how to work with intents and thread handlers. To learn more, checkout the next tutorial.
 

Top Bottom