Loading...
Home
  • News
    • Android News
    • Droidcon News
  • Conferences
    • Conference Videos
    • Upcoming Conferences
    • Become a Partner
    • Past Events
  • Community
    • droidcon Team
    • Forums
    • Keep Me Informed
    • How to Hold a Droidcon
  • Jobs
    • jobs.droidcon.com
Sign In

Global CSS

 

In-App Updates for Android Made Easier

 

 
Nikolai Kotchetkov
Lean Android Developer
Publlished: August 10, 2019
Tweet
Share
 

 

Keeping your app up-to-date on your users’ devices enables them to try new features, as well as benefit from performance improvements and bug fixes. Although some users enable background updates when their device is connected to an unmetered connection, other users may need to be reminded to update. In-app updates is a Play Core library feature that introduces a new request flow to prompt active users to update your app.

developer.android.com

Google announced in-app update feature at Google I/0 2019. The related implementation guide contains enough clues on how to implement both FLEXIBLE and IMMEDIATE update ‘flavors’. However the suggested approach may not work perfect especially in multi-activity applications. In this article I’ll try to highlight some key points of implementing in-app update in a complex real-world app and introduce a small library born as a result of these efforts.

 

motorro/AppUpdateWrapper

A wrapper for Android AppUpdateManager to simplify in-app update flow. A complete lifecycle-aware component to take a...

github.com

 

 

The focus of the story will be on a FLEXIBLE flow as carrying out a background update task requires considerably greater effort than IMMEDIATE flow.

The article assumes you already have some experience in implementing in-app update for Android. Otherwise please check out the official implementation guide or some introductory story like this one:

 

Exploring in-app updates on Android

I'm sure there has often been a time when you've needed to send out an app update that has some form of urgency - maybe...

medium.com

 

 

Managing a flow state

 

Complex update state
Two states of update flow

 

The FLEXIBLE flow provides background update checking and downloading while user continues to interact with application UI. AppUpdateManagerchecks for update for you and updates you with state changes while update is being downloaded. Starting an update check in your activity onResumehandler seems to be a good point to start the flow so the UI interaction takes place only at the topmost activity. If update is available you start the update flow and AppUpdateManager pops up a new activity-for-result to confirm update:

 

Download consent window

 

Suppose, user confirms update, update manager starts download… So far so good just like in an official guide.

But what if user cancels? The onActivityResult handler will receive RESULT_CANCELED result code. Having update check in subsequent onResume handler will bring the consent screen back unless we implement some special processing and memoing of user interaction.

What we have here is AppUpdateManager is handling a ‘system’ update statebut the burden of the update UI flow lays on the developer. And things become trickier if you add multi-activity setup, screen rotation, a telephone call that interrupts application flow, you name it… Plus you need to get a correct state of update if your activity has started while say a download is underway.

 

Designed for single activity application

Born to be single…

Photo by Sasha Freemind on Unsplash

 

From what I’ve learned while trying to plug-in flexible flow in our main application it seems the AppUpdateManager is designed (and tested) for a single-activity design.

  • Some effort in lifecycle management required to make multi-activity application to start download in one activity and to complete update in another.
  • I haven’t managed to make several instances of AppUpdateManager work along each other in an application with several activities. Have to use a singleton instance which is an obvious solution but…
  • AppUpdateManager fails to handle more than one active InstallStateUpdatedListener. If they try to unsubscribe within event dispatch manager crashes with ConcurrentModificationException. Take a look at this test:

 

Crashes when unsubscribing

 

AppUpdateWrapper to the rescue!

 

Wraps to protect…
Photo by dylan nolte on Unsplash

 

All in all, after some considerable time of trial and error spent I’ve come to the solution which IMO simplifies most of the update flow implementation in your application.

Here is how the minimum activity setup looks like with AppUpdateWrapperat your side:

Minimum activity setup for update flow

 

Features

  • You only need to implement a single AppUpdateView interface with minimum of three required methods to run both IMMEDIATE and FLEXIBLE flows. You may implement it in your activity as shown above or delegate to any view component of your choice.
  • The AppUpdateWrapper is a lifecycle-aware component designed as a plugin.
  • Works nice across multiple activities including a workaround to crashes with event listeners.
  • Under the hood based on a ‘state-machine’ pattern for clean and testable code to test each key point.

Bonus

As a bonus the FLEXIBLE flow of a library offers a built-in solution to postpone subsequent update prompts if user has already canceled the update:

 

The library implements couple of basic use-cases:

  • alwaysOn — to ask user every time the update is found
  • forOneDay — to postpone the next update prompt for one day since cancellation

From this article you’ve learnt about the possible difficulties to build a smooth update flow UI for Android application. Also the AppUpdateWrapperlibrary was presented to you as possible solution to problems above-mentioned. For the further details on using AppUpdateWrapper in your application please refer to the Github repository. If you have any questions about the library or in-app updates then please do reach out. It will also be great if you could try the solution in your application and to contribute to the code or test scenario.

 

motorro/AppUpdateWrapper

A wrapper for Android AppUpdateManager to simplify in-app update flow. A complete lifecycle-aware component to take a...

github.com

 

 
 

Tags: Android App Development, Updates, UI, Android, AndroidDev

 

View original article at: 


 

 

Android News
Successful Live Coding
Successful Live Coding

By Piotr Ślesarew

My life has many journeys and the most inspiring are those that bring me personal joy and satisfaction. Programming is one of them, and the more I am into it the more exciting it is. I used to be pretty shy in terms of publishing my knowledge and sharing my thoughts with a broader audience. Every single public speech that I made was a disaster and a huge drama.

By ProAndroidDev -
Android News
TL!!DR Android Programming Tips #1 — Context
TL!!DR Android Programming Tips #1 — Context

By Ozan Topuz

It is the context of the current state of the application/object. 
getApplicationContext() and getApplicationContext() are both instances of Context. So when should you use them and what is the best way to use a context? Let’s clarify them with examples.

By ProAndroidDev -
Android News
Creating an Expandable Floating Action Button in Android — Part 2
Creating an Expandable Floating Action Button in Android — Part 2

By TJ

It’s been a little over a year since the post above, and a lot of things can change in a year. Specifically, I’ve since moved to Kotlin as my primary language for Android development, and I’ve found a cleaner and more aesthetically pleasing way to create an expandable floating action button in Android; let’s talk more about the latter.

 

By ProAndroidDev -
Android News
Phantom Types in Kotlin
Phantom Types in Kotlin

By Danny Preussler

While working on my KotlinConf presentation about types I stumbled upon this post by Maximiliano Felice about Phantom types with Scala. The idea: prevent objects from having an illegal state or forbid illegal operation at compile time. The example given was a class Door. A door is either open or closed. In Kotlin this would look like:

By ProAndroidDev -

Follow us

Team droidcon

Get in touch with us

Write us an Email

 

 

Quicklinks

> Code of Conduct

> Terms and Conditions

> How to hold a conference

> FAQs

> Imprint

Droidcon is a registered trademark of Mobile Seasons GmbH Copyright © 2019. All rights reserved.

powered by Breakpoint One