Modern Android Architecture via MVVM + JetPack

The first Android Development SDK was released in 2007—14 years ago as of this writing. The Android SDK has evolved—significantly—in that time, yet the basic paradigm of loosely coupled layout (usually in XML files) with code in Java (more recently, Kotlin), has largely remained the same.

Now, two years after the launch of Jetpack, we’ve seen tremendous adoption by apps, from large developer teams to those just getting started.

What’s new in Jetpack

App Basics

App Manifest Overview

Every app project must have an AndroidManifest.xml file (with precisely that name) at the root of the project source set. The manifest file describes essential information about your app to the Android build tools, the Android operating system, and Google Play.

Activity

An activity is a single, focused thing that the user can do. Almost all activities interact with the user, so the Activity class takes care of creating a window for you in which you can place your UI with #setContentView.

To be of use with android.content.Context #startActivity, all activity classes must have a corresponding <activity> declaration in their package’s AndroidManifest.xml.

  • MainActivity.kt: What the app does
  • activity_main.xml: What the app looks like

Toasts overview

A toast provides simple feedback about an operation in a small popup. It only fills the amount of space required for the message and the current activity remains visible and interactive. Toasts automatically disappear after a timeout.

1
Toast.makeText(context, text, duration).show()

Late-initialized properties and variables

Normally, properties declared as having a non-null type must be initialized in the constructor. However, it is often the case that doing so is not convenient.

To handle such cases, you can mark the property with the lateinit modifier:

1
2
3
4
5
6
7
8
9
10
11
public class MyTest {
lateinit var subject: TestSubject

@SetUp fun setup() {
subject = TestSubject()
}

@Test fun test() {
subject.method() // dereference directly
}
}

Tools attributes reference

When you build your app, the build tools remove these attributes so there is no effect on your APK size or runtime behavior.

Android Studio supports a variety of XML attributes in the tools namespace that enable design-time features (such as which layout to show in a fragment) or compile-time behaviors (such as which shrinking mode to apply to your XML resources).

Design-time view attributes

  • The following attributes define layout characteristics that are visible only in the Android Studio layout preview.

  • tools: instead of android:

  • Intended for: <View>

Layout

A layout defines the structure for a user interface in your app, such as in an activity. All elements in the layout are built using a hierarchy of View and ViewGroup objects. A View usually draws something the user can see and interact with. Whereas a ViewGroup is an invisible container that defines the layout structure for View and other ViewGroup objects, as shown in figure 1.

**Figure 1.** Illustration of a view hierarchy, which defines a UI layout

Load the XML Resource

When you compile your app, each XML layout file is compiled into a View resource. You should load the layout resource from your app code, in your Activity.onCreate() callback implementation.

1
2
3
4
fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout)
}

Android styling: themes vs styles

Both themes and styles use the same <style> syntax but serve very different purposes. You can think of both as key-value stores where the keys are attributes and the values are resources. Let’s take a look at each.

What’s in a style?

tyles are a collection of view attributes; specific to a single type of widget

1
2
3
4
5
6
7
<!-- Copyright 2019 Google LLC.	
SPDX-License-Identifier: Apache-2.0 -->
<style name="Widget.Plaid.Button.InlineAction" parent="…">
<item name="android:gravity">center_horizontal</item>
<item name="android:textAppearance">@style/TextAppearance.CommentAuthor</item>
<item name="android:drawablePadding">@dimen/spacing_micro</item>
</style>

What’s a theme?

A theme is a collection of named resources which can be referenced later by styles, layouts etc.

1
2
3
4
5
6
7
<!-- Copyright 2019 Google LLC.	
SPDX-License-Identifier: Apache-2.0 -->
<style name="Theme.Plaid" parent="…">
<item name="colorPrimary">@color/teal_500</item>
<item name="colorSecondary">@color/pink_200</item>
<item name="android:windowBackground">@color/white</item>
</style>

Reference

Data Binding

The Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.

Layouts are often defined in activities with code that calls UI framework methods. For example, the code below calls findViewById() to find a TextView widget and bind it to the userName property of the viewModel variable:

1
2
3
findViewById<TextView>(R.id.sample_text).apply {
text = viewModel.userName
}

The following example shows how to use the Data Binding Library to assign text to the widget directly in the layout file. This removes the need to call any of the Java code shown above. Note the use of @{} syntax in the assignment expression:

1
2
<TextView
android:text="@{viewmodel.userName}" />

Binding components in the layout file lets you remove many UI framework calls in your activities, making them simpler and easier to maintain. This can also improve your app’s performance and help prevent memory leaks and null pointer exceptions.

Constraint Layout

ConstraintLayout allows you to create large and complex layouts with a flat view hierarchy (no nested view groups). It’s similar to RelativeLayout in that all views are laid out according to relationships between sibling views and the parent layout, but it’s more flexible than RelativeLayout and easier to use with Android Studio’s Layout Editor.

reference

Build a Responsive UI with ConstraintLayout

ConstraintLayout

Android Jetpack’s Navigation component helps you implement navigation, from simple button clicks to more complex patterns, such as app bars and the navigation drawer. The Navigation component also ensures a consistent and predictable user experience by adhering to an established set of principles.

The Navigation component consists of three key parts that are described below:

  • Navigation graph: An XML resource that contains all navigation-related information in one centralized location. This includes all of the individual content areas within your app, called destinations, as well as the possible paths that a user can take through your app.
  • NavHost: An empty container that displays destinations from your navigation graph. The Navigation component contains a default NavHost implementation, NavHostFragment, that displays fragment destinations.
  • NavController: An object that manages app navigation within a NavHost. The NavController orchestrates the swapping of destination content in the NavHost as users move throughout your app.

As you navigate through your app, you tell the NavController that you want to navigate either along a specific path in your navigation graph or directly to a specific destination. The NavController then shows the appropriate destination in the NavHost.

Intents and Intent Filters

An Intent is a messaging object you can use to request an action from another app component. Although intents facilitate communication between components in several ways, there are three fundamental use cases:

  • Starting an activity

    An Activity represents a single screen in an app.

  • Starting a service

    A Service is a component that performs operations in the background without a user interface.

  • Delivering a broadcast

    A broadcast is a message that any app can receive.

The rest of this page explains how intents work and how to use them. For related information, see Interacting with Other Apps and Sharing Content.

Intent types

  • Explicit intents specify which application will satisfy the intent, by supplying either the target app’s package name or a fully-qualified component class name.
  • Implicit intents do not name a specific component, but instead declare a general action to perform, which allows a component from another app to handle it.

Jetpack Compose Overview

Jetpack Compose represents a major shift of the Android UI development paradigm—a direction which will be easier, faster and ultimately result in less expensive, higher quality software that better meets the needs of companies field software in a competitive mobile software marketplace.

Jetpack combines the existing Android support libraries and components and wraps them into a new set of components (including a couple of new ones) for managing things like background tasks, navigation, paging, and life-cycle management, as well as UI features like emoji and layout controls for various platforms like Android Wear, Auto and TV, as well as some more foundation features like AppCompact and Test.

Jetpack Components

Here’s a round up of the latest updates in Jetpack — an extended version of our What’s new in Jetpack talk!

Online Courses and Certification

Udacity - Developing Android Apps with Kotlin

Learn to architect and develop Android apps in the Kotlin programming language using industry-proven tools and libraries. Create apps in less time, writing less code, with fewer errors.

Google - Jetpack Compose

Learn about Compose, a modern toolkit for building native Android UI.

Associate Android Developer Certification

Accelerate your move toward a career in mobile app development. Learn to build simple Android apps with our Android Basics in Kotlin training — no programming experience necessary. Then, take the Associate Android Developer Certification exam to gain recognition for your skills as a developer.

Author

Haojun(Vincent) Gao

Posted on

2021-08-04

Updated on

2022-06-22

Licensed under

Comments