Asynchronous queries in Android.
Tags: java, android, tristan
Published: 2021-08-10 23:57:11

#Introduction
- This series is going to be dedicated to the basic of Android development. Join me and let us try to build and understand some cool stuff. All the resources I used to create this post can be found on ticketnote [HERE](https://ticketnote.dev/ticket/zye72vzYXxL0Y8FoFsDm). 

###A quick word
- This tutorial is going to be on, `how to retrieve a single row from a Room database`. I am creating it out of my general frustration on trying to find the answer on what seems to be a very simple and easy problem to solve. With this tutorial I hope you save you from spending 9 hours knee deep in documentation. With that being said lets get started.

- I also want to point out that what your about to see is most definitely 100% spaghetti code. So if you notice any code that could be improved please let me know in the comments down below.

###YouTube version
[HERE](https://www.youtube.com/watch?v=SyrBlylLfXc&list=PLmZTujG6l1BrHHzV67M0Sa45bdxH0qAoi&index=8) 

###The DAO
- When we are creating queries for a Room database we always start with the relevant data access object(DAO). Since we are not making a `@Update`,`@Insert` or `@Delete` query we know that we will being using SQL to query the database. The query that we create to return one row will be below:

```
    //CALL A QUERY TO GET ONLY A SPECIFIC CALF
    @Query("SELECT * FROM calf_table WHERE id = :calfId")
    public Calf getCalf(int calfId);
```
- If any of the calf and cow references are confusing to you, don't worry they are just named that way because this code is all from my app that I am developing. You can ignore the calf type.

- Now lets dive a little deeper into the SQL code and under stand what it is saying.

###SELECT
- Select determines which columns to include in our query set and then returns the rows that have those columns. Despite actually being the first `query clause`(the capital letters determine what is a query clause) it is actually one of the last clauses that the  database server evaluates.

###FROM
- Identifies the tables from which to draw data. It also identifies how the tables should be joined but since we are only querying one table we don't need to worry about it.

###WHERE 
- This clause is the mechanism for filtering out unwanted rows from our result set.
- lastly the `:` is how we specify a parameter we defined ourselves.

- So to put all this together and to translate the SQL query to human speak we get, `show all the columns and rows from the calf_table, where the id is equal to the id we specified.`.


###The Repository
- Now that we understand our query, lets dive into our repository. If you are unfamiliar with what a repository is, it is just a architecture technique used to allow for loose coupling in databases.

```
public Calf getCalf(int calfId) throws ExecutionException, InterruptedException {
        Future<Calf> calf =  CalfRoomDatabase
                .databaseWriteExecutor.submit(new Callable<Calf>() {
            @Override
            public Calf call()  {
                return mCalfDao.getCalf(calfId);
            }
        });
        //GET SHOULD WAIT UNTIL WE GET WHAT WE WANT
        Calf gettingCalf = calf.get();
        return gettingCalf;
    }

```

- As you can see this method starts off very normal but you will notice `throws ExecutionException, InterruptedException` in the method declaration. Before we can understand what is going on here we need to understand exceptions as a whole.

###What is an Exception
- If you are ready know about exceptions feel free to skip this part.
- An exception is actually short hand for `exceptional event` but we will stick to exception. An exception is an event which occurs during the execution of a program that disrupts the normal flow of said program.

###What happens when an exception is encountered?
- When an error occurs within a method, the method creates an object then hands it off to the runtime system. The object, called an exception, contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handling it to the runtime system is called `throwing an exception`.

###How an exception is handled
- When an exception is thrown, the runtime system searches the callstack(data structure containing method calls ) for a method that contains a block of code that handles the exception. This block of code is called the `exception handler`. The search begins with the method in which the error occurred and proceeds through the callstack in the reverse order in which the methods were called. When the appropriate handler is found the runtime system passes the exception to the handler. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler. We will talk more about the exception handler when we get into the `try catch blocks`.

###Types of exceptions 
- There are actually 3 types of exceptions:

**1) Checked exceptions**
**2) Errors**
**3) Runtime exception**

- The exceptions in our code, `ExecutionException` and `InterruptedException` are both considered `checked exceptions` so we will only be talking about checked exceptions.

###Checked exceptions
- Exceptions that fall under this category are exceptions that a well written application should anticipate and recover from. When dealing with checked exceptions we must abide by the `Catch or specify Requirements`, which basically says that we must use a try catch block to deal with the exceptions.

**ExecutionException :** thrown when attempting to retrieve the result of a task that aborted by throwing an exception.

**InterruptedException :**thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity.

###Throws
```
 public Calf getCalf(int calfId) throws ExecutionException, InterruptedException {
```

- Now that we have a better understanding on what an exception is, lets talk about the `throws` keyword. When throws is used in the method declaration like we are using it, it describes the types of exceptions the method might encounter. It is also used to tell us and the compiler that we are going to deal with the exceptions higher up and the callstack. Which means a method that calls this method is going to deal with the exceptions via a `try catch block`, which we will see later

- So long story show `throws` is used to signify two things:

**1)** The types of exceptions the method is going to encounter
**2)** Another method is going to handle the exceptions

- Now lets move on to the future objects.

###Future Class:
```
Future<Calf> calf =  CalfRoomDatabase
                .databaseWriteExecutor.submit(new Callable<Calf>() {
            @Override
            public Calf call()  {
                return mCalfDao.getCalf(calfId);
            }
        });
        //GET SHOULD WAIT UNTIL WE GET WHAT WE WANT
        Calf gettingCalf = calf.get();
        return gettingCalf;

```
- Notice in the code above that we have defined the return type of calf to be Future<Calf>, which is a Future object containing a Calf object. 

###What is a Future object?
- A Future represents the result of an asynchronous computation and it provides methods to check if computation is complete, to wait for its completion and to retrieve the results of the computation.

###databaseWriteExecutor
- This is actually of type ExecutorService which we used in our database class to create a thread pool. The tutorial I used to do this is [HERE](https://developer.android.com/codelabs/android-room-with-a-view#7)
- **thread pool :** consists of worker threads that are used to execute multiple tasks. tasks being asynchronous requests.

- Then we call `databaseWriteExecutor.submit()` which is available to use through the `ExecutorService` interface. submit() accepts a `callable` object, which allows our asyncronous tasks to return a value. In our case the return type is `Future<Calf>`.

###Callable
```
new Callable<Calf>() {
            @Override
            public Calf call()  {
                return mCalfDao.getCalf(calfId);
            }
        }
```
- So a `Callable` is very similar to a runnable, meaning that they are both intended to be executed by a thread. In our case we are using worker threads, which are basically just less memory intensive threads. The big difference between the two is that callable can return a value, if you try to use a runnable you will never be able to get a value. You will only get null. 

```
@Override
            public Calf call()  {
                return mCalfDao.getCalf(calfId);
            }

```
- When we create a callable it will call its call() method and that method is what will return a Future object. Inside this method is where we make a call to our DAO. `mCalfDao.getCalf(calfId);`

```
Calf gettingCalf = calf.get();
        return gettingCalf;
```
- Lastly we call `get()` which will wait, if necessary for the computation to complete and to retrieve the results. This method is what we turns the Future object into our Calf object.


###ViewModel
- This method is inside of a new file that is used to hold the ViewModel. If you are unfamiliar with a ViewModel, you can read more about it [HERE](https://developer.android.com/topic/libraries/architecture/viewmodel)

```
public Calf getCalf(int calfId) throws ExecutionException, InterruptedException {
        
       Calf calf = mRepository.getCalf(calfId);
        return calf;

    }
```
- As you can see we have already talked about everything here. We use `throws` to say, handle the exceptions somewhere else. We simply use this method to call the method on the repository.


###Our Fragment
- This code is inside of a Fragment, which is just a java object that extends Fragment. It actually happens inside the `onViewCreated` method.

```
            try {
                Calf calf = calf = mCalfViewModel.getCalf(calfId);
               String tagNumber = calf.getTagNumber();
               String description = calf.getDetails();

               updateTagNumber.setText(tagNumber);
               updateTextDescription.setText(description);

            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
```

- The first thing to notice is the `try and catch blocks`. These blocks are necessary when dealing with checked exceptions like we are. Like I stated earlier, checked exceptions must abide by the `catch or specify requirement`. This requirement states that we must handle exceptions in try and catch blocks. We use the try block to enclose code that might throw an exception. Then we provide catch blocks that will each catch one type of exception. you can do whatever you want inside those catch blocks but for use right now we are just printing out the error.

- Lastly that is it. Than is how we make a single asynchronous request to our room database.

#Conclusion
- Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on [Twitter](https://twitter.com/TristAndroidDev).