Mobius Tutorial for Android: Getting Started
Learn about Mobius, a functional reactive framework for managing state evolution and side effects and see how to connect it to your Android UIs. By Massimo Carli.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Mobius Tutorial for Android: Getting Started
30 mins
- Getting Started
- Understanding Mobius Principles and Concepts
- Mobius Update Function
- The Mobius Workflow
- Modeling Your App
- Defining External Events
- Capturing User Interactions
- Defining Effects
- Defining Your Model
- Defining Effects Feedback Events
- Describing Your App
- Memory Game Update Function
- Implementing Back-Out Functionality
- Handling Effects
- Mobius and Android
- Where to Go From Here?
The Mobius Workflow
In the previous section, you learned that the main concepts in Mobius are:
- Models
- Events
- Effects
- Init function
- Update function
This implies that creating an app with Mobius means defining these same concepts in the domain of the app itself. This leads to a sequence of steps you can follow every time in the design and implementation of your app. The process has a name: the Mobius workflow. It consists of the following four steps:
- Model or MoFlow (Short for “Mobius Flow”)
- Describe
- Plan
- Build
It’s interesting now to see each of these in detail in the context of the app.
Modeling Your App
Models in Mobius can represent different concepts like:
- The current state of the app.
- Events generated by a user action.
- External events.
- Events resulting from a side effect’s execution.
Usually, the steps are the following:
- Define external events.
- Capture user interactions.
- Define effects.
- Define effects feedback events.
Defining External Events
In your case, the app doesn’t handle any external events, but it could. Imagine, for instance, if the game was multiplayer and you received an invitation from a friend. In that case, the app would display a dialog so you could accept or decline the invitation.
To track all the items Mobius needs to implement, you create a table like the following. This is the MoFlow table.
Because you don’t have external events, the table is initially empty. No problem! You’ll deal with user interactions next.
Capturing User Interactions
User interactions represent the possible events you need to handle when the user interacts with the app. In your case, you can start entering the name of the events related to navigation, which will allow you to move from the menu screen to credits or the game screen. When you navigate, you might also need to return to the previews screen. Upon adding these events, the MoFlow table becomes the following:
As you’ll see later, when you select PLAY, you’ll display a screen like the following with all the cards covered:
The game consists of flipping the cards in pairs and trying to find cards with the same value. If the values of the cards are the same, they remain flipped, changing their color. If the values are different, the program flips them back, and the game continues. The game ends when all the cards remain flipped. Every time the player flips a card, the number of moves increases by one. When the player finds a pair, the number of moves decreases by two. The goal is to find all the pairs in the fewest moves.
Understanding how the game works allows you to define new events. In this case, only one is related to user interaction, which you call FlipCard
. As you’ll see very soon, the game generates other types of events when you flip a pair of cards, depending on whether you’ve found a matching pair.
At this point, the MoFlow table looks like this:
Here, you have a clear idea of all the actions users can do and how the app should handle them.
Defining Effects
Now, you need to think about the effects the previous events can generate. When players flip a pair of cards, the game needs to understand what to do. If the cards are different, the game waits for a few seconds and flips the cards back to cover them. You can model this behavior with a DelayedWrongPair
effect. In the same way, if the cards contain the same value, the game waits some time and sets the pair as found. You model this using a DelayedCompletedPair
effect. In this case, the game also needs to check if all the pairs have been found and, if so, end the game. You can model this with the GameFinished
effect.
As you’ll see later, you also need an ExitApplication
effect to exit from the app when you go back to the initial menu.
With these effects, the MoFlow table becomes:
GameFinished
effect just makes the game wait and then send, as you’ll see later, an EndGame
event to signal the end of the game.
Defining Your Model
In this step, you need to define the model as a representation of your app’s view. In the app for this tutorial, you basically need to handle two different aspects:
- Navigation
- Game State
To handle the navigation, you just need a property of the model that tells the UI what composable function to execute. The game’s state consists of which cards are available as well as which ones and how many of them the player has matched. If the app is big, you can decide to implement different models. In this case, you just have a single model that you implement in the CardGameModel
class.
Now, the MoFlow table becomes:
As mentioned before, the view of your app will use all the data in the model to render the information it needs.
Defining Effects Feedback Events
Now, you have CardGameModel
to keep track of the app’s current state. When the user flips a card, you generate a FlipCard
event. If the card you flip is the first, you just need to update the model to update the UI. If the card you flip is the second, the system needs to check if the two cards have the same value. When the cards match, you generate a DelayedCompletedPair
effect, which waits a few milliseconds and then flips the cards to a different color. If the cards have different values, you generate a DelayedWrongPair
, which also waits a few milliseconds and then flips the cards back.
How do the effects notify the system that some time has elapsed and the cards need to change their state? Each effect has the option to notify its completion by sending an event called an effect feedback event.
In this app, when the cards are equal, the DelayedCompletedPair
effect will notify its completion by sending a SetPairAsDone
event. If the cards are different, the DelayedWrongPair
effect will notify its completion by sending a RestorePair
event. Finally, the GameFinished
effect will send an EndGame
to notify the completion of the game.
These are events, so the last version of the MoFlow for the app is the following: