Avin's Blog

Android Basics: Async Task

May 20, 2020
Tags: Android, Android Basics, Github API, AsyncTask, Github Repository App,

AsyncTask is used to run tasks that might take some time on other thread so that the UI thread is not blocked and the UI keeps running smoothly while the task keeps running in the background.

AsyncTask is now deprecated, but I do believe it is going to be supported for a while. The alternatives are to use the standard java.util.concurrent or Kotlin concurrency utilities instead.

Before we get started with AsyncTask I want to add an OnClickListener to the Search Button so that we can respond to clicks. You can find more here. Right now are are going to create a toast which is going to display our search term.

// In onCreate after we did our findViewById's.

        mSearchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Do something when the search button is clicked.
                Context context = v.getContext();
                Toast.makeText(context, mSearchQueryEditText.getText(), Toast.LENGTH_LONG).show();
                
                // TODO: Query Github API
            }
        });

This is what it looks like

app

Creating an AsyncTask

So AsyncTask has 4 steps:

  1. onPreExecute() : invoked on the UI thread
  2. doInBackground(Params…): invoked on the background threads
  3. onProgressUpdate(Progress …): invoked on the UI thread
  4. onPostExecute(Result): invoked on the UI thread

As the names suggest onPreExecute is invoked before doInBackground, anything you want to do before running the task goes here. Then we have doInBackground, this is where the task runs, we could also call publishProgress which sends progress updates to onProgressUpdate, it can be used to update things like progress bars or percentages. onPostExecute is where we get the result of our task.

So lets build a simple AsyncTask for our app.

// This would be outside onCreate since we are creating a new class

    private class QueryGithubAPITask extends AsyncTask<URL, Void, String>{
        @Override
        protected String doInBackground(URL... urls) {
            try {
                return NetworkUtils.getResponseFromHttpUrl(urls[0]);
            }catch (IOException e){
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            mSearchResultTextView.setText(s);
        }
    }
private class QueryGithubAPITask extends AsyncTask<URL, Void, String>

We specify the type of parameters the three functions(in the order doInBackground, onProgressUpdate, onPostExecute) take at the very top, since we are not using onProgressUpdate we put Void.

        @Override
        protected String doInBackground(URL... urls) {
            try {
                return NetworkUtils.getResponseFromHttpUrl(urls[0]);
            }catch (IOException e){
                e.printStackTrace();
            }
            return null;
        }

Here all we are doing is to get a url and then pass it into a function that we previously created in our network utils in the doInBackground functions and then using the result we get and pass that on to onPostExecute.

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            mSearchResultTextView.setText(s);
        }
    }

Since doInBackground returns a String onPostExecute accepts a String as its argument. We use the result from the doInBackground, in our case a String and set it as text in one of the TextViews.

Using the AsyncTask

Now that we have our AsyncTask setup we want to use it when we press the search button. This is pretty straight forward, we change the search buttons onClickListener to check if we have an empty search bar and if we have a search term we search it by executing our AsyncTask.

        mSearchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String githubSearchQuery = mSearchQueryEditText.getText().toString();

                // Making sure our search bar(EditText) isn't empty
                if(githubSearchQuery.equals("")){
                    Context context = v.getContext();
                    Toast.makeText(context, "Please enter a search term.", Toast.LENGTH_SHORT).show();
                }else{
                    // Building the url with the search term
                    URL url = NetworkUtils.buildUrl(githubSearchQuery);

                    // Calling our AsyncTask
                    new QueryGithubAPITask().execute(url);
                }
            }
        });

Lets try and search something to see if our app works

app

A good exercise would be to try and add a progress bar so that when we are fetching JSON we show the progress bar and when we are done fetching we hide the progress bar and show our edit text.

app

So the app works, but all we see is a wall of text with lots of JSON. A good idea would be to parse the JSON and display only the names of repos. Let’s explore how we could do that in the next post.

You can find the code here.




This website may contain affiliate links, meaning I may receive a small commission for products purchased through these link at no extra cost to you.