<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Victor Brandalise</title>
    <description>The latest articles on DEV Community by Victor Brandalise (@victorbrndls).</description>
    <link>https://dev.to/victorbrndls</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F633105%2Fd9a5eb1b-5d3d-4c15-8da6-a0677f177ff9.png</url>
      <title>DEV Community: Victor Brandalise</title>
      <link>https://dev.to/victorbrndls</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/victorbrndls"/>
    <language>en</language>
    <item>
      <title>From Nothing to Material Transitions</title>
      <dc:creator>Victor Brandalise</dc:creator>
      <pubDate>Thu, 24 Jun 2021 00:20:06 +0000</pubDate>
      <link>https://dev.to/victorbrndls/from-nothing-to-material-transitions-5gm</link>
      <guid>https://dev.to/victorbrndls/from-nothing-to-material-transitions-5gm</guid>
      <description>&lt;p&gt;Animations rarely change the core functionally of an app but you can’t deny that they make a big difference for the user. When an app has great animations everything looks more fluid, it’s easier to understand how things fit together.&lt;/p&gt;

&lt;p&gt;Transitions are used when you’re moving from one screen to another and you want to apply animations to one or multiple elements. In this article I’ll show you how to implement them in your app.&lt;/p&gt;

&lt;p&gt;We’ll start with an app that has no animations and add the needed ones to improve it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gPxZKtMv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d1255eb63fd300cbb7abd8_765063-1-min.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gPxZKtMv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d1255eb63fd300cbb7abd8_765063-1-min.gif" alt=""&gt;&lt;/a&gt;Without transitions / With transitions&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;

&lt;p&gt;Before we start, make sure you’re not using the wrong library version.&lt;/p&gt;

&lt;p&gt;If you’re using &lt;code&gt;androidx.appcompat:appcompat:1.3.0&lt;/code&gt; you’ll have to manually specify &lt;code&gt;androidx.fragment:fragment-ktx:1.3.5&lt;/code&gt; because &lt;code&gt;appcompat:1.3.0&lt;/code&gt; depends on &lt;code&gt;fragment:1.3.4&lt;/code&gt; that introduced a bug related to fragment transitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8omQIUBi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8omQIUBi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/image.png" alt=""&gt;&lt;/a&gt;See the “Bug Fixes” section&lt;/p&gt;

&lt;p&gt;I was getting an &lt;code&gt;IndexOutOfBoundsException&lt;/code&gt; exception when messing around with shared transitions and I took me a while to discover that the fragment library was the problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
        at java.util.ArrayList.get(ArrayList.java:437)
        at androidx.fragment.app.FragmentTransitionImpl.setNameOverridesReordered(FragmentTransitionImpl.java:183)
        at androidx.fragment.app.DefaultSpecialEffectsController.startTransitions(DefaultSpecialEffectsController.java:665)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s get started&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Knowledge
&lt;/h2&gt;

&lt;p&gt;If no return transition is set, the transition system will automatically reverse the enter transition when navigating back.&lt;/p&gt;

&lt;p&gt;By default, transitions run on all child views within their scene root hierarchy. For example, if you have a &lt;em&gt;RecyclerView&lt;/em&gt;, the animation will be applied to it and to its children. If that’s not the behavior you expect, set &lt;code&gt;android:transitionGroup="true"&lt;/code&gt; on the view group to disable that. You can also apply it to the out most view in your layout to make the fragment animate as a whole.&lt;/p&gt;

&lt;p&gt;If you have views that are populated after the fragment is created (a &lt;em&gt;RecyclerView&lt;/em&gt; for example) you need to tell the transition system to wait before starting the transitions. To do that you need to call &lt;code&gt;postponeEnterTransition&lt;/code&gt; to postpone the transitions and call &lt;code&gt;startPostponedEnterTransition&lt;/code&gt; when you’ve populated your views.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fade Through
&lt;/h2&gt;

&lt;p&gt;We’ll start with one of the simplest transitions, &lt;strong&gt;MaterialFadeThrough&lt;/strong&gt;. The fade through pattern is used for transitions between UI elements that do not have a strong relationship to each other.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3BAg8uiA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d12ab41d6d4a004e378ddc_10443-min.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3BAg8uiA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d12ab41d6d4a004e378ddc_10443-min.gif" alt="FadeThrough"&gt;&lt;/a&gt;FadeThrough&lt;/p&gt;

&lt;p&gt;The transition here consists of going from the items fragment to the cart fragment. On the first fragment we define &lt;code&gt;exitTransition&lt;/code&gt; and &lt;code&gt;reenterTransition&lt;/code&gt; to &lt;code&gt;MaterialFadeThrough&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;On the destination fragment we define the same transition but on &lt;code&gt;enterTransition&lt;/code&gt; and &lt;code&gt;returnTransition&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you’re using a &lt;em&gt;RecyclerView&lt;/em&gt; you might need to postpone the enter transition on the destination fragment. To learn how to do that, take a look at the &lt;strong&gt;Basic Knowledge&lt;/strong&gt; section.&lt;/p&gt;

&lt;p&gt;This transition is a good option for &lt;strong&gt;navigating between fragments&lt;/strong&gt; when you have a bottom navigation bar. The fade is subtle but adds a nice touch to the navigation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In a fade through transition, outgoing elements first fade out. Next, incoming elements fade in while scaling in overall size from 92% to 100%. The element scaling starts at 92%, rather than 0%, to avoid drawing excessive attention to the transition. The scale animation is applied only to incoming elements in order to emphasize new content over the old.&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;&lt;a href="https://material.io/design/motion/the-motion-system.html" rel="noreferrer noopener"&gt;The motion system&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Fade
&lt;/h2&gt;

&lt;p&gt;The fade transition is usually used with dialogs, menus, or things that fit within the bounds of the existing screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6iVInZLW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d27186e7b3ed006ef8aa02_718377-min.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6iVInZLW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d27186e7b3ed006ef8aa02_718377-min.gif" alt="MaterialFade"&gt;&lt;/a&gt;MaterialFade&lt;/p&gt;

&lt;p&gt;Implementing the &lt;code&gt;MaterialFade&lt;/code&gt; transition is basically the same as implementing the &lt;code&gt;MaterialFadeThrough&lt;/code&gt; transition, the only difference is the transition name.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When entering, elements use a fade and scale in overall size from 80% to 100%. The scale animation starts at 80%, rather than 0%, to avoid drawing excessive attention to the transition. When exiting, elements simply fade out. The scale animation is only applied to entering elements. This places emphasis on new content (entering elements) over old content (exiting elements).&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;&lt;a href="https://material.io/design/motion/the-motion-system.html" rel="noreferrer noopener"&gt;The motion system&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What’s the difference between Fade and Fade Through?
&lt;/h3&gt;

&lt;p&gt;They look very similar but by looking at the specification we can see one main difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fade&lt;/strong&gt; – Scales from 80% to 100%&lt;br&gt;&lt;br&gt;
&lt;strong&gt;FadeThrough&lt;/strong&gt; – Scales from 92% to 100%&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared Axis
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;MaterialSharedAxis&lt;/code&gt; transition is well suited for cases when you want to represent some kind of spatial relationship. Opening a search page would be good example, when the user searches something, the content below is expected to change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g-ct6LGa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d275d41c0fef0036ea5a00_970787-min.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g-ct6LGa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d275d41c0fef0036ea5a00_970787-min.gif" alt="MaterialSharedAxis"&gt;&lt;/a&gt;MaterialSharedAxis&lt;/p&gt;

&lt;p&gt;For this transition to look good you need a pair of fragments to animate simultaneously. Their transitions will run together to create a directional animation.&lt;/p&gt;

&lt;p&gt;You can control the transition direction by specifying the &lt;code&gt;forward&lt;/code&gt; property on &lt;code&gt;MaterialSharedAxis&lt;/code&gt;. In the forward direction, targets of the transition will scale out.&lt;/p&gt;

&lt;p&gt;On this example we’re using the Z axis but you should give the X and Y axis a try to see what they look like.&lt;/p&gt;

&lt;p&gt;For the transition to look great you need to specify the same &lt;code&gt;forward&lt;/code&gt; value for &lt;code&gt;exitTransition&lt;/code&gt; = &lt;code&gt;enterTransition&lt;/code&gt; and &lt;code&gt;reenterTransition&lt;/code&gt; = &lt;code&gt;returnTransition&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Container Transformation
&lt;/h2&gt;

&lt;p&gt;This is the transition I love the most, &lt;code&gt;MaterialContainerTransform&lt;/code&gt; is used as a shared element transition, that means it’s used to transition the view’s size, position, etc from the start state to the end state.&lt;/p&gt;

&lt;p&gt;The Container Transformation is used a lot when you have a &lt;em&gt;RecyclerView&lt;/em&gt; that’s already displaying some portion of the content that’ll be available at another screen. By using this transition you can animate the change from one place to another.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fM9s-_af--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d3c8dea98a2c00c6549ff2_608871.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fM9s-_af--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d3c8dea98a2c00c6549ff2_608871.gif" alt="MaterialContainerTransform"&gt;&lt;/a&gt;MaterialContainerTransform&lt;/p&gt;

&lt;p&gt;First we need to specify a &lt;code&gt;transitionName&lt;/code&gt; on the view we wish to transition. Transition names have to be unique, that’s why I’m adding &lt;code&gt;layoutPosition&lt;/code&gt; to the end of the transition name. If you’re using a &lt;em&gt;RecyclerView&lt;/em&gt;, you should do this when binding your &lt;em&gt;ViewHolder&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now on the end layout file, add a &lt;code&gt;transitionName&lt;/code&gt; to the view the animation will end on.&lt;/p&gt;

&lt;p&gt;We want the transition to start when the item is clicked, on the item clicked handler we have to tell the transition system the views from the start state that will map to the end state. For example the &lt;code&gt;icon&lt;/code&gt; that was clicked on the &lt;em&gt;RecyclerView&lt;/em&gt; will transition to the view on the end layout that has &lt;code&gt;R.string.item_detail_icon_transition_name&lt;/code&gt; as &lt;code&gt;transitionName&lt;/code&gt;. The &lt;code&gt;transitionName&lt;/code&gt; you specified on the &lt;em&gt;ViewHolder&lt;/em&gt; is just used by android to keep track of things, you won’t use it anywhere else.&lt;/p&gt;

&lt;p&gt;Finally we specify the &lt;code&gt;MaterialContainerTransform&lt;/code&gt; on the destination fragment. &lt;code&gt;drawingViewId&lt;/code&gt; is the view that’ll be used as a plane for the animation, if you’re using Navigation specify your &lt;em&gt;NavController&lt;/em&gt; view.&lt;/p&gt;

&lt;p&gt;If you want your animation to follow an arced path, you also need to specify the path motion.&lt;/p&gt;

&lt;p&gt;There are many ways to customize your transitions, you can learn more about them &lt;a href="https://material.io/design/motion/customization.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As I’ve said before, if you don’t specify a return transition, Android will automatically use the enter transition reversed.&lt;/p&gt;

&lt;p&gt;Take a look at the last GIF again, the &lt;code&gt;MaterialContainerTransform&lt;/code&gt; looks good but everything else uses a rough transition. Let’s learn how we can use many transitions together to achieve a better end result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debug mode
&lt;/h3&gt;

&lt;p&gt;In some cases you might need some help to understand what’s happening behind the transition and there’s a simple thing that can help you with that. &lt;code&gt;MaterialContainerTransform&lt;/code&gt; has a &lt;code&gt;isDrawDebugEnabled&lt;/code&gt; property that adds visual information to the transition.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IoOr5wno--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d27b2136373500706b0161_424997-min.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IoOr5wno--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d27b2136373500706b0161_424997-min.gif" alt="MaterialContainerTransform"&gt;&lt;/a&gt;MaterialContainerTransform &lt;/p&gt;

&lt;h2&gt;
  
  
  Mixing transitions
&lt;/h2&gt;

&lt;p&gt;We’ve learn learned about the 4 transitions provided by Material individually, now let me show you how I used 3 of them together to create an animation that is pleasing to the eyes.&lt;/p&gt;

&lt;p&gt;First I started by using the &lt;code&gt;MaterialSharedAxis&lt;/code&gt; transition on the list fragment, it works well because the views reduce size from 100% to 92%, that helps to focus on the icon animation.&lt;/p&gt;

&lt;p&gt;Then I added the &lt;code&gt;MaterialFadeThrough&lt;/code&gt; transition to the destination fragment but I excluded the icon from that animation because it’s already being animated by &lt;code&gt;MaterialContainerTransform&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By doing just that the end result is much better&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y9FrB9zU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d3cb2e1be1440029f578d1_308606-min.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y9FrB9zU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/final_60d3cb2e1be1440029f578d1_308606-min.gif" alt="Mixing transitions"&gt;&lt;/a&gt;Mixing transitions&lt;/p&gt;

&lt;p&gt;If you have any doubts you can find the &lt;a href="https://github.com/victorbrndls/BlogProjects/tree/material-transitions"&gt;source code here&lt;/a&gt; or contact me.&lt;/p&gt;

&lt;p&gt;The best way to learn is by doing, go and apply the knowledge you’ve acquired here to a concrete example. I’d enjoy seeing what you can accomplish. I hope this article was helpful for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://material.io/blog/android-material-motion"&gt;https://material.io/blog/android-material-motion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.stylingandroid.com/category/animation/transition/"&gt;https://blog.stylingandroid.com/category/animation/transition/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://codelabs.developers.google.com/codelabs/material-motion-android"&gt;https://codelabs.developers.google.com/codelabs/material-motion-android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://material.io/design/motion/the-motion-system.html"&gt;https://material.io/design/motion/the-motion-system.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@julianhochgesang?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Julian Hochgesang&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/move?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://victorbrandalise.com/from-nothing-to-material-transitions/"&gt;From Nothing to Material Transitions&lt;/a&gt; first appeared on &lt;a href="https://victorbrandalise.com"&gt;Victor Brandalise&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>technology</category>
      <category>android</category>
    </item>
    <item>
      <title>How to Show an Activity on Lock Screen instead of a Notification</title>
      <dc:creator>Victor Brandalise</dc:creator>
      <pubDate>Thu, 10 Jun 2021 23:10:25 +0000</pubDate>
      <link>https://dev.to/victorbrndls/how-to-show-an-activity-on-lock-screen-instead-of-a-notification-34dk</link>
      <guid>https://dev.to/victorbrndls/how-to-show-an-activity-on-lock-screen-instead-of-a-notification-34dk</guid>
      <description>&lt;p&gt;Today we’re gonna learn how to show a full screen activity instead of a notification when the device is locked.&lt;/p&gt;

&lt;p&gt;By default Android will show the same notification it shows when the device is unlocked but in some cases, such as a phone call, you might want to display a full screen activity.&lt;/p&gt;

&lt;p&gt;You can find the &lt;a href="https://github.com/victorbrndls/BlogProjects/tree/lockscreen-notification"&gt;source code here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating The Notification
&lt;/h2&gt;

&lt;p&gt;Let’s start by creating a simple notification that’ll be used later to show an Activity on the look screen.&lt;/p&gt;

&lt;p&gt;The first thing we need to do before creating the notification is creating the channel to display it.&lt;/p&gt;

&lt;p&gt;First we retrieve the &lt;code&gt;NotificationManager&lt;/code&gt; from &lt;code&gt;NotificationManagerCompat&lt;/code&gt;. That’s the interface used for dealing with notifications on Android. Then we create a &lt;code&gt;NotificationChannel&lt;/code&gt; that takes the channel’s id, name and importance as arguments. It’s advised to use &lt;code&gt;NotificationManager.IMPORTANCE_HIGH&lt;/code&gt; for increasing the chances of the notification appearing as a heads up notification. We also change the &lt;code&gt;lockscreenVisibility&lt;/code&gt; to &lt;code&gt;Notification.VISIBILITY_PUBLIC&lt;/code&gt; to tell Android that the notification can be shown on the lock screen. Finally we call &lt;code&gt;notificationManager.createNotificationChannel&lt;/code&gt; to register the channel.&lt;/p&gt;

&lt;p&gt;Up until Android Nought (25), there’s no need to create notification channels, that’s why there’s a guard cause at the beginning of the method.&lt;/p&gt;

&lt;h3&gt;
  
  
  When Should I Create the Channel?
&lt;/h3&gt;

&lt;p&gt;There’s no problem in calling &lt;code&gt;createNotificationChannel&lt;/code&gt; multiple times with the same channel, Android will ignore it if there’s an existing channel with the same id.&lt;/p&gt;

&lt;p&gt;You should register your channels as early as possible, preferably when &lt;code&gt;Application.onCreate&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Channels are immutable&lt;/strong&gt; , if you need to change some channel configuration you’ll either have to delete the app or change the channel’s id.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Simple Notification
&lt;/h3&gt;

&lt;p&gt;Now that we have created a channel, we can proceed to creating the notification.&lt;/p&gt;

&lt;p&gt;First we start by creating a &lt;code&gt;PendingIntent&lt;/code&gt;, that’s the intent that will be called when the notification is clicked, here we’ll simply start an activity. Then we call &lt;code&gt;NotificationCompat.Builder&lt;/code&gt; to define how the notification will look like. The &lt;code&gt;CHANNEL_ID&lt;/code&gt; parameter has to have the same id we used earlier to create the channel. If you want to learn how to customize you notification you can take a look at the &lt;a href="https://developer.android.com/training/notify-user/build-notification"&gt;Android Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The next step is simply calling &lt;code&gt;notificationManager&lt;/code&gt; to show the notification. The notification id can be any number, it’s used only if you need to interact with the notification later.&lt;/p&gt;

&lt;p&gt;That’s what you should see when your notification is displayed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7e5azGSk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/Screenshot-2021-06-08-at-20-42-18-Photo-Google-Photos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7e5azGSk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/Screenshot-2021-06-08-at-20-42-18-Photo-Google-Photos.png" alt=""&gt;&lt;/a&gt;Heads Up Notification&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Lock Screen Activity
&lt;/h2&gt;

&lt;p&gt;Now we’ll create the Activity that’ll be displayed on the lock screen. That activity is very similar to a normal activity but there are 2 things you need to change for it to appear on the lock screen.&lt;/p&gt;

&lt;p&gt;The first thing is calling &lt;code&gt;showWhenLockedAndTurnScreenOn&lt;/code&gt; after &lt;code&gt;onCreate&lt;/code&gt; to define that the activity can appear on the lock screen and that the screen should be turned on when it appears. I added the method to the activity but you can easily add that as an extension to Activity in case you use it in other places.&lt;/p&gt;

&lt;p&gt;The second thing is changing the manifest definition by adding &lt;code&gt;launchMode&lt;/code&gt; and &lt;code&gt;showOnLockScreen&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That’s it, you’ve created a activity that can appear on the lock screen. The last thing we need to do is to tell Android that we want that activity to appear on the lock screen instead of the notification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding the Activity to Notification
&lt;/h3&gt;

&lt;p&gt;We’ll have to modify the &lt;code&gt;createNotification&lt;/code&gt; method we defined earlier. We need to create another &lt;code&gt;PendingIntent&lt;/code&gt; that’ll start the activity that’ll be shown on the lock screen. We then pass that intent to &lt;code&gt;setFullScreenIntent&lt;/code&gt;. It’s also important to add a category such as ALARM or CALL for increasing the chances of it appearing on the lock screen.&lt;/p&gt;

&lt;p&gt;Here’s the end result&lt;/p&gt;
Full Screen Activity on Lock Screen






&lt;h3&gt;
  
  
  It’s not Working !!!
&lt;/h3&gt;

&lt;p&gt;For some of you the activity might not appear on the lock screen and that’s because of your phone, not all phones allow full screen intents by default. I have a &lt;em&gt;Xiaomi&lt;/em&gt; and it’s not enabled by default.&lt;/p&gt;

&lt;p&gt;To enable it you have to go to the &lt;strong&gt;app configuration&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Other permissions&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Show On Lock screen&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bFhfAMiZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/1623282460476-COLLAGE-1024x768.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bFhfAMiZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/06/1623282460476-COLLAGE-1024x768.jpg" alt=""&gt;&lt;/a&gt;Enable App to Appear on Lock Screen&lt;/p&gt;

&lt;p&gt;The notification will also not appear if you have an existing notification with the same id that has not been dismissed. Ideally you should cancel the notification by calling &lt;code&gt;notificationManager.cancel(id)&lt;/code&gt; when the lock screen activity is destroyed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Android notifications are a great way to notify your users they need to do something but they might not be work well when the phone is locked. Full screen activities come to solve that problem, allowing you to show the activity even if the phone is locked.&lt;/p&gt;

&lt;p&gt;The source code can be found &lt;a href="https://github.com/victorbrndls/BlogProjects/tree/lockscreen-notification"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://medium.com/simform-engineering/how-to-manage-incoming-video-call-for-every-android-os-version-with-fcm-notifications-68b8f2e3c9eb"&gt;How to manage incoming video call for every Android OS version with FCM notifications&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.android.com/training/notify-user/build-notification#urgent-message"&gt;Show an urgent message&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@rami_alzayat?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Rami Al-zayat&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/phone-screen?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://victorbrandalise.com/how-to-show-activity-on-lock-screen-instead-of-notification/"&gt;How to Show an Activity on Lock Screen instead of a Notification&lt;/a&gt; first appeared on &lt;a href="https://victorbrandalise.com"&gt;Victor Brandalise&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>technology</category>
      <category>android</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>In-depth look at gRPC for Android</title>
      <dc:creator>Victor Brandalise</dc:creator>
      <pubDate>Tue, 01 Jun 2021 01:05:00 +0000</pubDate>
      <link>https://dev.to/victorbrndls/in-depth-look-at-grpc-for-android-5af0</link>
      <guid>https://dev.to/victorbrndls/in-depth-look-at-grpc-for-android-5af0</guid>
      <description>&lt;p&gt;This article walks you through the most important concepts you need to know to understand gRPC. The concepts range from understanding how an HTTP/2 connection works to learning how to model Protocol Buffers correctly.&lt;/p&gt;

&lt;p&gt;By the end of this article you’ll have learned most of what you need to know to use gRPC effectively in Android.&lt;/p&gt;

&lt;p&gt;I’ll be using the following libraries:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;build.gradle&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;com.google.protobuf:protobuf-gradle-plugin:0.8.14&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;_ &lt;strong&gt;app/build.grdle&lt;/strong&gt; _&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;api 'io.grpc:grpc-kotlin-stub:1.1.0'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;api 'io.grpc:grpc-protobuf-lite:1.38.0'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;implementation 'io.grpc:grpc-android:1.38.0'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;implementation 'io.grpc:grpc-okhttp:1.38.0'&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find the &lt;a href="https://github.com/victorbrndls/BlogProjects/tree/grpc-android"&gt;source code here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Everything I say here refers to how the Kotlin library implements the gPRC protocol and it might be different from how other libraries implement it. The content of this article was curated from the resources listed at the end of the page.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP/2
&lt;/h2&gt;

&lt;p&gt;HTTP/2 was introduced to fix many problems HTTP/1 has. The main ones are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP/1.x clients need to use multiple connections to achieve concurrency and reduce latency; &lt;/li&gt;
&lt;li&gt;HTTP/1.x does not compress request and response headers, causing unnecessary network traffic; &lt;/li&gt;
&lt;li&gt;HTTP/1.x does not allow effective resource prioritization, resulting in poor use of the underlying TCP connection;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In contrast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP/2 reduces latency by enabling full request and response multiplexing, &lt;/li&gt;
&lt;li&gt;HTTP/2 minimizes protocol overhead via efficient compression of HTTP header fields, &lt;/li&gt;
&lt;li&gt;HTTP/2 adds support for request prioritization and server push.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Binary framing layer
&lt;/h3&gt;

&lt;p&gt;HTTP/1 transits its information encoded in US-ASCII. HTTP/2 on the other hand encodes its information in binary. This single change has a big impact on the message size. The HTTP semantics, such as verbs, methods, and headers, are unaffected, but the way they are encoded while in transit is different, this is achieved by adding the binary framing layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/web/fundamentals/performance/http2#binary_framing_layer"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yyhvtyig--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/binary_framing_layer01.svg" alt="Binary framing layer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both client and server must use the new binary encoding mechanism to understand each other: an HTTP/1.x client won’t understand an HTTP/2 only server, and vice versa.&lt;/p&gt;

&lt;p&gt;HTTP/2 also splits its messages into smaller parts called frames, each of which is encoded in binary format.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streams, messages, and frames
&lt;/h3&gt;

&lt;p&gt;_ &lt;strong&gt;Stream&lt;/strong&gt; _: A bidirectional flow of bytes within an established connection, which may carry one or more messages. Each  &lt;strong&gt;stream ** has a unique identifier. A single HTTP/2 connection has one or more **streams&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Message&lt;/em&gt;&lt;/strong&gt; : A complete sequence of &lt;strong&gt;frames&lt;/strong&gt; that map to a logical request or response &lt;strong&gt;message&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;_ &lt;strong&gt;Frame&lt;/strong&gt; _: The smallest unit of communication in HTTP/2, each containing a frame header, which at a minimum identifies the &lt;strong&gt;stream&lt;/strong&gt; to which the frame belongs. The most common headers are HEADERS and DATA.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/web/fundamentals/performance/http2#streams_messages_and_frames"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Do06Iklu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/streams_messages_frames01.svg" alt="Streams, messages, and frames"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s just a simple explanation of what HTTP/2 is like but it’s enough for understanding the next concept. Now we’re gonna take a look at how gRPC’s channels leverage HTTP/2.&lt;/p&gt;

&lt;h2&gt;
  
  
  Channel
&lt;/h2&gt;

&lt;p&gt;A channel is basically an interface for sending messages to one or more servers. Channels represent virtual connections to an endpoint, which in reality may be backed by many HTTP/2 connections.&lt;/p&gt;

&lt;p&gt;Channels do much more than just sending messages, they do name resolution, establish a TCP connection (with retries and backoff) and TLS handshakes. Channels can also handle errors on connections and reconnect. We’ll see how that happens at the Retry section.&lt;/p&gt;

&lt;p&gt;To create a channel you just need the server’s host and port. The &lt;code&gt;context&lt;/code&gt; is optional but it helps to manage the channel state.&lt;/p&gt;

&lt;p&gt;To create a simple abstraction for users, the gRPC API exposes information about the channel by defining 5 possible states:&lt;/p&gt;

&lt;h4&gt;
  
  
  CONNECTING
&lt;/h4&gt;

&lt;p&gt;The channel is trying to establish a connection, the steps involved are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name resolution – retrieving the IP address from the hostname;&lt;/li&gt;
&lt;li&gt;TCP connection establishment – establishing a connection using the three-way handshake process;&lt;/li&gt;
&lt;li&gt;TLS handshake if you’re using a secure connection – establishing a secure connection by negotiating what version of SSL/TLS will be used in the session, which cipher suite will encrypt communication, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of these steps fail, the channel transitions to &lt;strong&gt;TRANSIENT_FAILURE&lt;/strong&gt; state.&lt;/p&gt;

&lt;h4&gt;
  
  
  TRANSIENT_FAILURE
&lt;/h4&gt;

&lt;p&gt;Something didn’t go as expected. There has been some failure (such as a TCP 3-way handshake timing out or a socket error).&lt;/p&gt;

&lt;p&gt;Channels in this state will eventually switch to the CONNECTING state and try to establish a connection again. You can define a custom retry policy to determine how the retry works.&lt;/p&gt;

&lt;p&gt;The amount of time the channel spends on this state increases overtime because retries have exponential backoff.&lt;/p&gt;

&lt;h4&gt;
  
  
  READY
&lt;/h4&gt;

&lt;p&gt;If the channel has successfully established a connection it transitions from &lt;strong&gt;CONNECTING&lt;/strong&gt; to &lt;strong&gt;READY&lt;/strong&gt; state.&lt;/p&gt;

&lt;p&gt;This is the state the channel has to be for it to be used to make RPC calls. In an ideal world this would be the state channels would always stay, but the world is not perfect. If some failure happens the channel will transition to &lt;strong&gt;TRANSIENT_FAILURE&lt;/strong&gt; state.&lt;/p&gt;

&lt;p&gt;Even if everything is okay the channel might change its state to &lt;strong&gt;IDLE&lt;/strong&gt; , let’s see why.&lt;/p&gt;

&lt;h4&gt;
  
  
  IDLE
&lt;/h4&gt;

&lt;p&gt;This is the initial state for channels as defined by &lt;code&gt;ConnectivityStateManager&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It’s a waste of resources for the client and for the server to keep a connection open if no data is being transmitted.&lt;/p&gt;

&lt;p&gt;The channel transitions to this state because there has been no activity in the channel for a specified &lt;strong&gt;IDLE_TIMEOUT&lt;/strong&gt;. The default value for &lt;strong&gt;IDLE_TIMEOUT&lt;/strong&gt; is 30 minutes. The minimum value is 1 minute.&lt;/p&gt;

&lt;p&gt;The activity can either be a new RPC call or an existing call that has not finished yet. Only channels that are &lt;strong&gt;READY&lt;/strong&gt; or &lt;strong&gt;CONNECTING&lt;/strong&gt; can switch to &lt;strong&gt;IDLE&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Any attempt to make a RPC on the channel will push the channel out of this state to &lt;strong&gt;CONNECTING&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Channels may receive a GOAWAY from the server to indicate the channel should transition to &lt;strong&gt;IDLE&lt;/strong&gt; to reduce resource waste.&lt;/p&gt;

&lt;h4&gt;
  
  
  SHUTDOWN
&lt;/h4&gt;

&lt;p&gt;Channels may enter this state either because the application explicitly requested a shutdown or if a non-recoverable error has happened during attempts to connect communicate. Channels that enter this state never leave it.&lt;/p&gt;

&lt;p&gt;Any new RPCs should fail immediately. Pending RPCs may continue running till the application cancels them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nrNZ3TU4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/image.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nrNZ3TU4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/image.png" alt="gRPC Channel State Machine"&gt;&lt;/a&gt;Channel’s States&lt;/p&gt;

&lt;p&gt;You can call &lt;code&gt;Channel#getState()&lt;/code&gt; to retrieve the channel state.&lt;/p&gt;

&lt;p&gt;That’s a good overview of Channels, you know how to create a simple channel and how it behaves in its lifecycle. Now we’re going to see how to configure the channel to change its behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Retry
&lt;/h3&gt;

&lt;p&gt;Unexpected things happen. The connection might be lost, the server may close the connection abruptly, etc. Channels attempt to hide these situations from the user by recovering automatically. I say attempt because some situations are not recoverable and there’s nothing the channel can do about that.&lt;/p&gt;

&lt;p&gt;A temporary connectivity loss can be recovered from but if you permanently lose the connection or if the server shuts down, there’s no way to recover.&lt;/p&gt;

&lt;p&gt;When retrying, the channel switches from the CONNECTING state to the TRANSIENT_FAILURE state back and forth until the connection is recovered or the retry expires. By default retries are done with exponential backoff.&lt;/p&gt;

&lt;p&gt;Some libraries allow you to define a custom retry policy. The Kotlin library allows you to define the max numbers of retries the channel is allowed to do.&lt;/p&gt;

&lt;p&gt;By default the channel retries 5 times. If you want to change that you can call &lt;code&gt;AndroidChannelBuilder#maxRetryAttempts(attempts)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you want to customize other parameters you’ll need to create a custom service configuration. The specification can be found at &lt;a href="https://github.com/grpc/grpc-proto/blob/master/grpc/service_config/service_config.proto#L130"&gt;service_config.proto&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The proto has to be converted to a map style on the Kotlin library. You can learn how to do that &lt;a href="https://grpc.github.io/grpc/core/md_doc_service_config.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Alive
&lt;/h3&gt;

&lt;p&gt;You’ve established a connection to the server. You’ve sent some messages and everything is working fine. Suddenly you try to send another message and it fails, there’re was a problem communicating to the server. If you have retry enabled, the channel will do its job to try to reconnect again but that’s not the best way to handle that.&lt;/p&gt;

&lt;p&gt;What if there was an way to discover a problem will happen the next time you send a message? Well that’s not 100% possible but there’s something very close to that in gRPC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep Alive&lt;/strong&gt; is the feature that allows you to achieve that. Keep Alive sends periodic pings to check if a channel is currently working, that’s done using HTTP/2 PINGs. If the ping is not acknowledged by the peer within a certain timeout period, the channel knows there’s a problem.&lt;/p&gt;

&lt;p&gt;Keep Alive is not enabled by default, you can enable it by specifying the keep alive interval on the channel builder.&lt;/p&gt;

&lt;p&gt;The above code causes the channel to send a ping to the server every 20 seconds and wait another 5 seconds for a response. If the server doesn’t acknowledge the ping, the channel considers the connection failed, closes the connection, and begins reconnecting.&lt;/p&gt;

&lt;p&gt;You might need to call &lt;code&gt;AndroidChannelBuilder#keepAliveWithoutCalls(true)&lt;/code&gt; if you’re not actively using the channel but would like it to keep pinging the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subchannel
&lt;/h2&gt;

&lt;p&gt;You’ll not likely work directly with Subchannels but it’s interesting to know why they exist. The Subchannel is used mainly for load balancing. For example, you want to send requests to &lt;em&gt;google.com&lt;/em&gt;. The resolver resolves &lt;em&gt;google.com&lt;/em&gt; to multiple backend addresses that serve &lt;em&gt;google.com&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For example, let’s suppose there’re 3 servers that serve &lt;em&gt;google.com&lt;/em&gt;. The parent Channel will create 3 Subchannels, 1 for each logical connection. You can use the parent channel only and it’ll handle all the load balancing logic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ncz5rD8J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/image-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ncz5rD8J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/image-1.png" alt="Channel with Subchannels"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we’ve learned how channels work and that they’re used to transport messages, let’s see how we can send messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protocol Buffers
&lt;/h2&gt;

&lt;p&gt;By default, gRPC uses &lt;strong&gt;protocol buffers&lt;/strong&gt; as the Interface Definition Language (IDL) for describing both the service and messages. It is possible to use other alternatives if desired.&lt;/p&gt;

&lt;p&gt;Protocol Buffers are not like JSON where you have data and structure together. It’s closer to Kotlin Interfaces, where you define a protocol specifying methods and fields. The only thing you care about is the protocol, how the protocol will be implemented doesn’t matter to you.&lt;/p&gt;

&lt;p&gt;In the example below, I created a protocol to define a book. It has an &lt;strong&gt;id&lt;/strong&gt; to identify each book and its title.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;message Book {
  int32 id = 1;
  string title = 2;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The protocol buffer defines an interface, for you to interact with the interface, you need an implemented version in your target language.&lt;/p&gt;

&lt;p&gt;If you’re using the &lt;code&gt;protobuf-gradle-plugin&lt;/code&gt;, when you build your project, the protobuf plugin will get called and generate the implementation for each proto in Java.&lt;/p&gt;

&lt;p&gt;By default the plugin will look for files under &lt;code&gt;app/src/main/proto&lt;/code&gt;. The generated files can be found at &lt;code&gt;app/build/generated/source/proto/buildType&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There’s much more to Protocol Buffer than we can cover here, if you want to learn more I recommend &lt;a href="https://developers.google.com/protocol-buffers/docs/kotlintutorial"&gt;Protocol Buffer Basics: Kotlin&lt;/a&gt; and &lt;a href="https://developers.google.com/protocol-buffers/docs/proto3"&gt;Language Guide (proto3)&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Service
&lt;/h2&gt;

&lt;p&gt;Services are where you define the methods you want to call with their parameters and return types. You can define the API of your service using &lt;strong&gt;Protocol Buffers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You should use &lt;strong&gt;CamelCase&lt;/strong&gt; for both the service name and any RPC method names.&lt;/p&gt;

&lt;p&gt;In the example below, I defined an interface that allows me to create books (CreateBook) and list books (ListBooks).&lt;/p&gt;

&lt;p&gt;The great thing about the Kotlin library for gRPC is that the generated classes support _ &lt;strong&gt;coroutines.&lt;/strong&gt; _&lt;/p&gt;

&lt;p&gt;The above code creates a connection to a server at &lt;em&gt;127.0.0.1&lt;/em&gt; on port &lt;em&gt;9000&lt;/em&gt;, the connection is then used by a channel that’s passed as argument to create the service. When &lt;code&gt;createBook&lt;/code&gt; is called the service dispatches the message to the channel that sends it the to server.&lt;/p&gt;

&lt;p&gt;We’ll not look into the server side because this article is focused on Android, but I recommend you looking into that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--svpXu4-g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/marc-olivier-jodoin-NqOInJ-ttqM-unsplash-1024x576.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--svpXu4-g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/marc-olivier-jodoin-NqOInJ-ttqM-unsplash-1024x576.jpg" alt="Ottawa road in the evening"&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@marcojodoin?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Marc-Olivier Jodoin&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/transportation?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  RPC
&lt;/h2&gt;

&lt;p&gt;We’ve seen what a service is, now let’s go back and understand it a little bit further. RPCs are in practice plain HTTP/2 streams.&lt;/p&gt;

&lt;p&gt;To define a method in Kotlin we use the &lt;code&gt;fun&lt;/code&gt; keyword. To define a method in gRPC we use the &lt;code&gt;rpc&lt;/code&gt; keyword. The method signature is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rpc MethodName(Request) returns (Response) {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’re 2 kinds of methods in gPRC. Unary and Streaming.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unary
&lt;/h3&gt;

&lt;p&gt;The client sends a single request to the server and gets a single response back, just like a normal function call. This is what you’ll likely be using the most. It maps closely to a REST request/response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streaming
&lt;/h3&gt;

&lt;p&gt;There’re 3 kinds of streaming&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server streaming RPCs&lt;/strong&gt; where the client sends a request to the server and gets a stream to read a sequence of messages back. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client streaming RPCs&lt;/strong&gt; where the client writes a sequence of messages and sends them to the server. Once the client has finished writing the messages, it waits for the server to read them and return its response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bidirectional streaming RPCs&lt;/strong&gt; where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;gRPC guarantees message ordering within an individual RPC call. For example, if the server sends messages 1,2,3 and 4, gRPC guarantees the client will receive them in the same order but doesn’t guarantee the client will actually receive them, the client may actually only receive 1,2 and 3.&lt;/p&gt;

&lt;p&gt;Streaming RPCs that &lt;strong&gt;return multiple messages&lt;/strong&gt; from the server won’t retry after the first message has been received. Streaming RPCs that &lt;strong&gt;send multiple messages&lt;/strong&gt; to the server won’t retry if the outgoing messages have exceeded the client’s maximum buffer size.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unary x Streaming
&lt;/h3&gt;

&lt;p&gt;For lower concurrent requests, both have comparable latencies. However, for higher loads, unary calls are much more performant.&lt;/p&gt;

&lt;p&gt;There is no apparent reason we should prefer streams over unary, given using streams comes with problems like complex implementation at the application level and poor load balancing as the client will connect with one server and ignore any new servers and lower resilience to network interruptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Success for both parties?
&lt;/h3&gt;

&lt;p&gt;In gRPC, both the client and server make their own independent and local determination about whether the remote procedure call (RPC) was successful. This means their conclusions may not match! An RPC that finished successfully on the server side can fail on the client side.&lt;/p&gt;

&lt;p&gt;For example, the server can send the response, but the reply can arrive at the client after their deadline has expired. The client will already have terminated with the status error DEADLINE_EXCEEDED. This should be checked for and managed at the application level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices For Protocol Buffers
&lt;/h2&gt;

&lt;p&gt;Most languages have a set of best practices that are followed by developers to improve the code quality. The same happens for Protocol Buffers. Here’re some that I’ve found:&lt;/p&gt;

&lt;p&gt;Do not use &lt;code&gt;google.protobuf.Empty&lt;/code&gt; as a request or response type. If you use Empty, then adding fields to your request/response will be a breaking API change for all clients and servers.&lt;/p&gt;

&lt;p&gt;For custom methods, they should have their own XxxResponse messages even if they are empty, because it is very likely their functionality will grow over time and need to return additional data.&lt;/p&gt;

&lt;p&gt;Each enum value should end with a semicolon, not a comma. The zero value enum should be the name of the enum itself followed by the suffix UNSPECIFIED.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum State {
    UNKNOWN = 0;
    STARTED = 1;
    RUNNING = 1;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;This is my first “big” article. It was really fun writing it, I learned a lot about gRPC. If you have any questions or suggestions, you can contact me on Twitter. I’m open to new ideas, if you want somebody to chat about programming, architecture, or different approaches in general, I’d be happy to chat with you. Thank you for reading this article.&lt;/p&gt;




&lt;h2&gt;
  
  
  Other articles
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://victorbrandalise.com/useful-kotlin-extensions-for-android/"&gt;Useful Kotlin Extensions for Android&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://victorbrandalise.com/android-lifecycle-scenarios-single-and-multi-activities/"&gt;Android Lifecycle Scenarios – Single and Multi Activities&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://victorbrandalise.com/android-lifecycle-revised/"&gt;Android Lifecycle Revised&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/grpc/retries?view=aspnetcore-5.0"&gt;Transient fault handling with gRPC retries | Microsoft Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://grpc.io/blog/deadlines/"&gt;gRPC and Deadlines | gRPC&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://john-millikin.com/effective-grpc"&gt;Effective gRPC&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cloud.google.com/apis/design/design_patterns"&gt;Common Design Patterns  |  Cloud APIs  |  Google Cloud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/protocol-buffers/docs/style"&gt;Style Guide  |  Protocol Buffers  |  Google Developers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://charles-thayer.medium.com/grpc-top-6-things-that-bite-newbies-dfa740ffc67d"&gt;gRPC: Top 6 Things that Bite Newbies | by Charles Thayer | Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cncf.io/blog/2018/08/31/grpc-on-http-2-engineering-a-robust-high-performance-protocol/"&gt;gRPC On HTTP/2: Engineering a robust, high performance protocol | Cloud Native Computing Foundation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cncf.io/blog/2018/07/03/http-2-smarter-at-scale/"&gt;HTTP/2: Smarter at scale | Cloud Native Computing Foundation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/web/fundamentals/performance/http2"&gt;Introduction to HTTP/2  |  Web Fundamentals  |  Google Developers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hpbn.co/http2"&gt;High Performance Browser Networking  |  O’Reilly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.ssl.com/article/ssl-tls-handshake-overview/"&gt;The SSL/TLS Handshake: an Overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/protocol-buffers/docs/kotlintutorial"&gt;Protocol Buffer Basics: Kotlin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@tvick?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Taylor Vick&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/server?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://victorbrandalise.com/in-depth-look-at-grpc-for-android/"&gt;In-depth look at gRPC for Android&lt;/a&gt; first appeared on &lt;a href="https://victorbrandalise.com"&gt;Victor Brandalise&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>technology</category>
      <category>grpc</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Useful Kotlin Extensions for Android</title>
      <dc:creator>Victor Brandalise</dc:creator>
      <pubDate>Thu, 13 May 2021 11:30:38 +0000</pubDate>
      <link>https://dev.to/victorbrndls/useful-kotlin-extensions-for-android-3ifc</link>
      <guid>https://dev.to/victorbrndls/useful-kotlin-extensions-for-android-3ifc</guid>
      <description>&lt;p&gt;Kotlin has many amazing features but one that stands out is extensions. Extensions are used to add functionality to existing classes.&lt;/p&gt;

&lt;p&gt;They are extremely useful at helping to reduce boiler plate code. The good thing is that you can add them to any class, including the ones from third-party libraries that you can’t modify.&lt;/p&gt;

&lt;p&gt;Most of the time we see &lt;em&gt;Extension functions&lt;/em&gt; but Kotlin also supports &lt;em&gt;Extension properties&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful Extension Functions
&lt;/h2&gt;

&lt;p&gt;Lets start with some extensions that make the code easier to read, the ones that improve the code quality over time by reducing boiler plate code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;p&gt;The Android API changes over time and something as simple as getting the color for a given ID can become not so simple. The extensions below helps reduce the boiler plate code associated with retrieving resources for a given ID.&lt;/p&gt;

&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;p&gt;We all know how repeating it’s to check whether the user has granted the permissions the app requires. The extension below can help with that. It doesn’t solve the whole problem but helps reduce the code size.&lt;/p&gt;

&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;p&gt;Copying some text or URL to the clipboard should be something very simple. It only works with plain text but that’s what we use most of the time, if you need to support other formats you can change it.&lt;/p&gt;

&lt;p&gt;Is there an URL in your app that the user needs to open the browser to view? Are you handling the case where the browser or equivalent app might be missing? The next extension abstracts most of what’s needed. You just need to give it the Uri and do something such as showing an error if there’s no app to resolve the intent.&lt;/p&gt;

&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;h3&gt;
  
  
  Date
&lt;/h3&gt;

&lt;p&gt;This extension is very useful if you need to log a date object over and over or send it via an API call. Something to notice here is that the ISO format is universal, it doesn’t change from country to country, I’ll show why that’s important later.&lt;/p&gt;

&lt;h4&gt;
  
  
  Usage
&lt;/h4&gt;

&lt;p&gt;Some other extensions that might be useful&lt;/p&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qYhXhGK6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/artur-tumasjan-42l3tjsJGyw-unsplash-1024x683.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qYhXhGK6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://victorbrandalise.com/wp-content/uploads/2021/05/artur-tumasjan-42l3tjsJGyw-unsplash-1024x683.jpg" alt=""&gt;&lt;/a&gt;Photo by &lt;a href="https://unsplash.com/@arturtumasjan?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Artur Tumasjan&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/bad-lego?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  All that glitters is not gold
&lt;/h2&gt;

&lt;p&gt;Many things including extensions can be abused. Some of them look good, but are actually disguised code smells.&lt;/p&gt;

&lt;p&gt;Let’s start with an useless extension. I was reading an article about extensions the other day and found this one.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;There’s no code reduction by using the extension. &lt;/li&gt;
&lt;li&gt;By using the extension the compiler will consider it a normal function call and refrain from optimizing the null case if possible. &lt;/li&gt;
&lt;li&gt;That’s bad use of OOP, we add methods to objects to “ask” them about something, null by definition is the absence of an something. An object is never null, what’s is null is the reference to an object.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Be careful with localization
&lt;/h3&gt;

&lt;p&gt;The extension below may look reasonable to most of us. It formats a Double to its decimal format.&lt;/p&gt;

&lt;p&gt;The dangerous thing about this code is that money is not formatted equally worldwide. In some countries you’ll see &lt;strong&gt;1,200.00&lt;/strong&gt; (comma first, dot after), in others &lt;strong&gt;1.200,00&lt;/strong&gt; (dot first, comma after). This is only a problem if the app is/will be used in many countries.&lt;/p&gt;

&lt;p&gt;My solution would be to add the formatting pattern to &lt;code&gt;strings.xml&lt;/code&gt; and create an extension on &lt;code&gt;Context&lt;/code&gt; to handle that. That way you can define the monetary format for each language and still use the same function.&lt;/p&gt;




&lt;h2&gt;
  
  
  Extension Properties
&lt;/h2&gt;

&lt;p&gt;Kotlin also allows us to add properties as extensions. I’ve not found an use case for them yet but it’s useful to know that it’s possible to use them.&lt;/p&gt;




&lt;p&gt;Thank you for reading. If there’s anything you disagree with, please leave a comment below so we can discuss it and arrive at a better solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Other articles
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://victorbrandalise.com/android-lifecycle-scenarios-single-and-multi-activities/"&gt;Android Lifecycle Scenarios – Single and Multi Activities&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://victorbrandalise.com/android-lifecycle-revised/"&gt;Android Lifecycle Revised&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover photo by &lt;a href="https://unsplash.com/@fran_?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Fran Jacquier&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/lego?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://victorbrandalise.com/useful-kotlin-extensions-for-android/"&gt;Useful Kotlin Extensions for Android&lt;/a&gt; first appeared on &lt;a href="https://victorbrandalise.com"&gt;Victor Brandalise&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>technology</category>
      <category>android</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Android Lifecycle Scenarios – Single and Multi Activities</title>
      <dc:creator>Victor Brandalise</dc:creator>
      <pubDate>Thu, 29 Apr 2021 01:04:20 +0000</pubDate>
      <link>https://dev.to/victorbrndls/android-lifecycle-scenarios-single-and-multi-activities-3gp3</link>
      <guid>https://dev.to/victorbrndls/android-lifecycle-scenarios-single-and-multi-activities-3gp3</guid>
      <description>&lt;p&gt;&lt;em&gt;These are my personal notes on the topic. Most of the content here is not mine. All sources can be found at the end of the article.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Activities are a main part of Android. Lifecycle methods is the way Android notifies state changes to the Activity. To provide a great user experience, you should know how to manage them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you haven’t read my article about Activity Lifecycles, you can read it &lt;a href="https://victorbrandalise.com/android-lifecycle-revised/"&gt;here&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Lets take a look at some common scenarios using a &lt;strong&gt;single&lt;/strong&gt; Activity&lt;/p&gt;

&lt;h2&gt;
  
  
  1. App is finished or restarted
&lt;/h2&gt;

&lt;p&gt;This scenario happens when there’s only one activity in the back stack and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user presses the Back button&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Activity.finish()&lt;/code&gt; method is called&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---4T7ccpq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/383/1%2AU_j3OP74jrPFoNvO2i7XzQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---4T7ccpq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/383/1%2AU_j3OP74jrPFoNvO2i7XzQ.png" alt="App is finished or restarted"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onSaveInstanceState&lt;/code&gt; is not called.&lt;br&gt;&lt;br&gt;
&lt;code&gt;onCreate&lt;/code&gt; doesn’t have a Bundle when the app is reopened.&lt;/p&gt;

&lt;p&gt;If there’s only one activity in the back stack, the app will be finished. To avoid that you can override &lt;code&gt;onBackPressed()&lt;/code&gt;, that way &lt;code&gt;onDestroy()&lt;/code&gt; won’t get called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Override
public void onBackPressed() {
   moveTaskToBack(true);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Configuration changes
&lt;/h2&gt;

&lt;p&gt;This scenario happens when there’s only one activity in the back stack and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The configuration changes, like a  &lt;strong&gt;rotation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;User resizes the window in multi-window mode (available in android 7.0)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PtNwAOn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/482/1%2ADCo7awxJ3KhnW88h365vhA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PtNwAOn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/482/1%2ADCo7awxJ3KhnW88h365vhA.png" alt="Configuration changes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The activity is completely destroyed, but the state is saved and restored for the new instance.&lt;br&gt;&lt;br&gt;
The Bundle in &lt;code&gt;onCreate()&lt;/code&gt; and &lt;code&gt;onRestoreInstanceState()&lt;/code&gt; is the same.&lt;/p&gt;

&lt;p&gt;Why is the Bundle sent to two methods?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onRestoreInstanceState()&lt;/code&gt; is called  &lt;strong&gt;only when recreating&lt;/strong&gt;  activity after it was  &lt;strong&gt;killed&lt;/strong&gt;  by Android. It is possible to restore the state in &lt;code&gt;onRestoreInstanceState()&lt;/code&gt;, but not very common. &lt;code&gt;onRestoreInstanceState()&lt;/code&gt; is called after &lt;code&gt;onStart()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Usually you restore your state in &lt;code&gt;onCreate()&lt;/code&gt;. &lt;code&gt;onCreate()&lt;/code&gt; is called before &lt;code&gt;onStart()&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. User navigates away
&lt;/h2&gt;

&lt;p&gt;This scenario happens when there’s only one activity in the back stack and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user presses the Home button&lt;/li&gt;
&lt;li&gt;The user switches to another app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, you’re browsing Twitter and you click on a notification that takes you to another app. When you switch back to Twitter the activity’s &lt;code&gt;onRestart()&lt;/code&gt; will called.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7e7dh96I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/441/1%2A3qxYnT2vRwrQVORi9mfUhw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7e7dh96I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/441/1%2A3qxYnT2vRwrQVORi9mfUhw.png" alt="User navigates away"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onSaveInstanceState()&lt;/code&gt; is used to save the app state in case the system kills the app’s process later on.&lt;/p&gt;

&lt;p&gt;This scenario is very similar to navigating from Activity A to Activity B, the only difference is that &lt;code&gt;onSaveInstanceState()&lt;/code&gt; is not called when navigating between activities.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. App is paused by the system
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Enabling Multi-window mode (API 24+) and losing the focus&lt;/li&gt;
&lt;li&gt;Another app partially covers the running app (a purchase dialog, a runtime permission dialog, a third-party login dialog…)&lt;/li&gt;
&lt;li&gt;An intent chooser appears, such as a share dialog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yjGTwSxj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/523/1%2Aj3blnCW082yMbQe5fkjMMg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yjGTwSxj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/523/1%2Aj3blnCW082yMbQe5fkjMMg.png" alt="App is paused by the system"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Doesn’t apply to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dialogs in the same app. Showing an AlertDialog or a DialogFragment won’t &lt;strong&gt;pause the underlying activity.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Notifications. User receiving a new notification or pulling down the notification bar won’t pause the underlying activity.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Now lets take a look at some common scenarios using &lt;strong&gt;multiple&lt;/strong&gt; Activities&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Navigate from Activity A to Activity B
&lt;/h2&gt;

&lt;p&gt;When activity A is created, &lt;code&gt;onCreate()&lt;/code&gt; is called. Then &lt;code&gt;onStart()&lt;/code&gt; is called. Once the user is able to interact with the app, &lt;code&gt;onResume()&lt;/code&gt;  is called. Now the user opens Activity B.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onPause()&lt;/code&gt; of activity A will get called. Then activity B’s &lt;code&gt;onCreate()&lt;/code&gt; ** ** followed by &lt;code&gt;onStart()&lt;/code&gt; and &lt;code&gt;onResume()&lt;/code&gt;. Finally activity A’s &lt;code&gt;onStop()&lt;/code&gt; is triggered.&lt;/p&gt;

&lt;p&gt;Here is the callbacks order&lt;/p&gt;

&lt;p&gt;Activity A -&amp;gt; &lt;code&gt;onCreate()&lt;/code&gt; , &lt;code&gt;onStart()&lt;/code&gt;, &lt;code&gt;onResume()&lt;/code&gt;, , &lt;code&gt;onPause()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Activity B -&amp;gt; &lt;code&gt;onCreate()&lt;/code&gt;, &lt;code&gt;onStart()&lt;/code&gt;, &lt;code&gt;onResume()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Activity A -&amp;gt; &lt;code&gt;onStop()&lt;/code&gt;, &lt;code&gt;onSaveInstanceState()&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Navigate from Activity B back to Activity A
&lt;/h2&gt;

&lt;p&gt;When the back button is pressed, Activity B’s &lt;code&gt;onPause()&lt;/code&gt; is triggered. Then activity A’s &lt;code&gt;onRestart()&lt;/code&gt; is called followed by &lt;code&gt;onStart()&lt;/code&gt; and &lt;code&gt;onResume()&lt;/code&gt;. After that activity B’s &lt;code&gt;onStop()&lt;/code&gt; gets called followed by &lt;code&gt;onDestroy()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is the callbacks order&lt;/p&gt;

&lt;p&gt;Activity B -&amp;gt; , &lt;code&gt;onPause()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Activity A -&amp;gt; &lt;code&gt;onRestart()&lt;/code&gt;, &lt;code&gt;onStart()&lt;/code&gt;, &lt;code&gt;onResume()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Activity B -&amp;gt; &lt;code&gt;onStop()&lt;/code&gt;, &lt;code&gt;onDestroy()&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;Thank you for reading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/androiddevelopers/the-android-lifecycle-cheat-sheet-part-i-single-activities-e49fd3d202ab"&gt;The Android Lifecycle cheat sheet — part I: Single Activities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/proggy-blast/lifecycle-methods-of-android-activity-scenario-based-question-8d3e14169297"&gt;Lifecycle methods of Android Activity — Scenario based Question&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/4096169/onsaveinstancestate-and-onrestoreinstancestate"&gt;onSaveInstanceState () and onRestoreInstanceState ()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@viazavier?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Laura Ockel&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/gear?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://victorbrandalise.com/android-lifecycle-scenarios-single-and-multi-activities/"&gt;Android Lifecycle Scenarios – Single and Multi Activities&lt;/a&gt; first appeared on &lt;a href="https://victorbrandalise.com"&gt;Victor Brandalise&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>technology</category>
      <category>android</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Android Lifecycle Revised</title>
      <dc:creator>Victor Brandalise</dc:creator>
      <pubDate>Sat, 24 Apr 2021 01:34:54 +0000</pubDate>
      <link>https://dev.to/victorbrndls/android-lifecycle-revised-1b98</link>
      <guid>https://dev.to/victorbrndls/android-lifecycle-revised-1b98</guid>
      <description>&lt;p&gt;The Activity class is an essential part of every Android app. Unlike traditional programming paradigms, the Android framework starts code in an Activity instance by invoking callback methods that correspond to specific stages of its lifecycle.&lt;/p&gt;

&lt;p&gt;The activity state changes when the user rotates the phone, responds to a notification, or switches to another app. When these state changes happen, Android uses lifecycle callback methods to notify the activity about them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.android.com/guide/components/activities/activity-lifecycle"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uV3vg5g1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://developer.android.com/guide/components/images/activity_lifecycle.png" alt="https://developer.android.com/guide/components/images/activity_lifecycle.png"&gt;&lt;/a&gt;A simplified illustration of the activity lifecycle&lt;/p&gt;

&lt;h4&gt;
  
  
  onCreate()
&lt;/h4&gt;

&lt;p&gt;This is the first callback called by the system. The activity is now on &lt;strong&gt;CREATED&lt;/strong&gt; state.&lt;/p&gt;

&lt;p&gt;You should perform basic application startup logic that should happen only once for the entire life of the activity, for example, associating the activity to a &lt;a href="https://developer.android.com/topic/libraries/architecture/viewmodel?hl=en"&gt;viewModel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you initialize something after &lt;code&gt;onCreate()&lt;/code&gt; is called, release or terminate it when &lt;code&gt;onDestroy()&lt;/code&gt; is called.&lt;/p&gt;

&lt;h4&gt;
  
  
  onStart()
&lt;/h4&gt;

&lt;p&gt;This is the second callback called by the system. The activity is now on &lt;strong&gt;STARTED&lt;/strong&gt; state. The activity is visible to the user but not yet interactive.&lt;/p&gt;

&lt;p&gt;You should execute code that maintains the UI.&lt;/p&gt;

&lt;h4&gt;
  
  
  onResume()
&lt;/h4&gt;

&lt;p&gt;This is the third callback called by the system. The activity is now on &lt;strong&gt;RESUMED&lt;/strong&gt; state. The user can now interact with the app. The app stays in this state until something happens to take focus away from the app. Such an event might be, for instance, receiving a phone call, the user’s navigating to another activity, or the device screen’s turning off.&lt;/p&gt;

&lt;p&gt;You should implement &lt;code&gt;onResume()&lt;/code&gt; to initialize components that you release during &lt;code&gt;onPause()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;These 3 commands are called on all activities you instantiate, they’re used to setup and make the activity available to the user. First the method is called, then the state changes. &lt;code&gt;onCreate()&lt;/code&gt; is called and after that the activity is on &lt;strong&gt;CREATED&lt;/strong&gt; state. The next 3 methods do that in the reverse order. The state changes to &lt;strong&gt;PAUSED&lt;/strong&gt; and after that &lt;code&gt;onPause()&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;The state changes&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;onCreate&lt;/td&gt;
&lt;td&gt;onDestroy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;onStart&lt;/td&gt;
&lt;td&gt;onStop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;onResume&lt;/td&gt;
&lt;td&gt;onPause&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  onPause()
&lt;/h4&gt;

&lt;p&gt;This is the first callback called to indicate the user is leaving the activity. The activity is now on &lt;strong&gt;PAUSED&lt;/strong&gt; state. It is no longer in the foreground.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onPause()&lt;/code&gt; execution is brief and should not be used to perform heavy operations. Don’t use &lt;code&gt;onPause()&lt;/code&gt; to save data, make network calls or execute database transactions. These operations should be executed when &lt;code&gt;onStop()&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;The user might decide to come back to the activity and &lt;code&gt;onResume()&lt;/code&gt; will be called. If that doesn’t happen, &lt;code&gt;onStop()&lt;/code&gt; is the next method.&lt;/p&gt;

&lt;h4&gt;
  
  
  onStop()
&lt;/h4&gt;

&lt;p&gt;This is the second callback called to indicate activity might be finishing. The activity is now on &lt;strong&gt;STOPPED&lt;/strong&gt; state. It is no longer visible. This happens every time you open a new activity that covers the whole screen.&lt;/p&gt;

&lt;p&gt;You should release almost all resources that aren’t needed while the user is not using it. If needed you should also make network calls or save data to the database.&lt;/p&gt;

&lt;p&gt;In some rare cases, the system might kill your process without calling &lt;code&gt;onDestroy()&lt;/code&gt;, so it’s important that you use &lt;code&gt;onStop()&lt;/code&gt; to release resources that might cause memory leak.&lt;/p&gt;

&lt;h4&gt;
  
  
  onDestroy()
&lt;/h4&gt;

&lt;p&gt;This is the third and last callback called to indicate activity is finishing. The activity is now on &lt;strong&gt;DESTROYED&lt;/strong&gt; state. This method is called by the system when &lt;code&gt;finish()&lt;/code&gt; is called, when the user dismisses the activity or because the configuration changed, for example, the user rotated the device.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens when you start another activity? &lt;a href="https://developer.android.com/guide/components/activities/activity-lifecycle#coordinating-activities"&gt;Source&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The order of lifecycle callbacks is always the same. Here’s the order of operations that occur when Activity A starts Activity B:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Activity A’s &lt;strong&gt;&lt;code&gt;onPause()&lt;/code&gt;&lt;/strong&gt; method executes.&lt;/li&gt;
&lt;li&gt;Activity B’s &lt;strong&gt;&lt;code&gt;onCreate()&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;onStart()&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;code&gt;onResume()&lt;/code&gt;&lt;/strong&gt; methods execute in sequence. (Activity B now has user focus.)&lt;/li&gt;
&lt;li&gt;Then, if Activity A is no longer visible on screen, its &lt;strong&gt;&lt;code&gt;onStop()&lt;/code&gt;&lt;/strong&gt; method executes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The sequence is always the same, making it easier for developers to manage transitions between them.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to call the super class?
&lt;/h3&gt;

&lt;p&gt;When overriding any of the methods, you may need to call the super class implementation. The rule of thumb&lt;sup&gt;&lt;a href="https://guides.codepath.com/android/Activity-Lifecycle#calling-the-super-class" rel="noreferrer noopener"&gt;1&lt;/a&gt;&lt;a href="https://stackoverflow.com/a/9626268/7207418" rel="noreferrer noopener"&gt;2&lt;/a&gt;&lt;/sup&gt; is that&lt;/p&gt;

&lt;p&gt;During initialization, you should always call the super class first&lt;br&gt;&lt;br&gt;
During de-initialization, you should do the work first before calling the super class&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://victorbrandalise.com/android-lifecycle-revised/"&gt;Android Lifecycle Revised&lt;/a&gt; first appeared on &lt;a href="https://victorbrandalise.com"&gt;Victor Brandalise&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>technology</category>
      <category>android</category>
    </item>
  </channel>
</rss>
