Android Instant Apps are the most exciting change to the Android ecosystem in years. Being able to use your app without installing it or even opening the Play Store to search for it doesn’t need much selling, but how do you actually implement that? What changes do you need to make to your current app so that it can be used piece-by-piece, without installation? In this talk we’ll go over the actual code changes made to allow our Stack Exchange app to be used as an Instant App. You’ll walk away with a better understanding of what it means to be an Instant App, what benefits it can provide to your business, and how to architect or modify your app to become one.
My name is Kasra, and I run the mobile team at Stack Overflow. That includes our mobile applications, and our mobile website. I am on my ninth year of Android development, I’ve been doing Android development since the first Android developer phone challenge and even when it was an emulator and we didn’t have keywords or anything.
These days I do a lot of Android dev and I do a lot of everything else. I’m going to talk about some stuff with a PM hat on, some stuff with a user perspective hat on and I might go on a rant about React at some point.
I’m here to talk to you about instant apps, because at Stack Overflow we do a lot of early access preview partnerships with Google, so I’ve been doing instant apps for a year and a half, and I’ve been excited about them for a very long time. I’ve been talking to my coworkers about it for a very long time, and they really don’t want to hear about it anymore, so I’m here to talk to all of you about it instead!
I’m going to talk about what an instant app is. Then we’re going to dive right into how to turn your app or codebase into an instant app.
We’re going to focus on the step-by-step processes. We’re going to talk about modules and packages. Then we’re going to zoom out a bit and cover everything else around this world. How do we actually do instant apps? How do you actually launch it? What are you doing, what are you trying to look for? We will also cover some of the business side stuff.
Let’s say I click a link in a Reddit app and I don’t have any other apps installed on my phone, but it’s a link to stackoverflow.com. It opens up the instant app, and it drops you into this question and answer view. You can look at all the content, you can interact with it, you can vote, you can add an answer, and you can add a comment, you can do whatever you want.
The really cool thing is that they didn’t do anything. They just clicked on a link. It could’ve been in the Reddit app, it could’ve been a link from someone sending them a text. It’s just someone saying look at this one piece of content and I’m showing you that exact content in my native view. There is actually a hybrid view, there’s a lot of web views for syntax highlighting, but it is native code.
As a developer, I want you to install my Android app, but I also want you to just get what you’re trying to get. Previously, you would go on a mobile website and there would be a little banner on the top that would say “Open in app.” Why would you click on that? You came here to do something, you’ve already got it, so you move on with your life.
The instant app is the same, so I’m not trying to get the user to install my full app. I could have a big button that says install the app, but I just want them to do what they came to do. They might click on “vote” and then hit back and move on with their lives, or they can install my app and browse around. If they try to browse around it will ask them to do that. It’s just trying to not get in their way, which sounds like a really low bar, but I’m just trying to not get in the way of the user so they can do what they’re trying to do.
What is an Instant App?
It’s your native app running instantly without installation. The first part is that you’re not writing a new app – you’re refactoring some stuff, but it’s nothing that you don’t already know. It’s a new way of thinking about what you already know. You don’t have to actually become an instant app developer, you already know how to make instant apps. It becomes really easy to make something from scratch that can handle being an instant app.
We’ll go into what the modules are and how you can do it, but the big key is: it’s your native app. It’s somewhat new code, it references new code, but it’s not distinct. It’s not something that’s in a different branch. It’s your regular app and it can do a subset of what your app does. It can’t do everything your app does, it can do just one specific thing.
For my case, the Stack Exchange app has a lot of stuff in it and it’s just the one subset of looking at a question and answer on Stack Overflow that is the instant app. If you try to add an answer, it asks you to install the app. If you do anything else, it asks for the installed app.
The high level overview of what it’s going to give you is that instant apps get the user to where they want to get to really fast. It changes your entire goal as a mobile developer from getting someone to install your app and engage, to getting them to actually do what they want to do.
For me, that’s interacting with our Q&A content, it’s adding a comment, it’s uploading an answer, and it’s adding a new answer. It’s all of the actual KPIs that everyone else looks at; that’s bigger than what my app’s downloads are.
Instant apps are a side entry. You can have an instant app that is pinned to the launch screen on Android and you can have someone open it up without installing anything. For the most part, they’re not clicking on something from a launcher, they’re clicking on a link in an email, a link in a text message, or a link in an app.
As far as similarities and differences, they’re the same project with the same codebase. It’s a new build variant in the same project; we’ll get into how the variants work, but it’s the exact same app with a different entrance into it. It can have sections of the app; it doesn’t have to have everything the app does, but it’s not a new thing. You’re not writing new code, and you’re not writing throwaway code. You’re going to be reusing a lot of code because it’s actually the exact same thing.
Get more development news like this
The end result is the same package identifier. It’s the same link on the Play Store, it’s the same exact thing as your app. The differences are when someone installs your app, there’s a lot of things that you get from that. When someone wants to interact with your company, and with your app, a lot of those go away on the instant app side. There’s a lot of restrictions we’ll get into in a second, but the entire flow of what is allowed, what you think you can do, and what someone has told you they’re okay with you doing, is totally different because all they did was click on a link. They didn’t actually go in the app store, and look at your permissions, hit yes.
On the installed app side, you can do anything on the Android API, you already know. On the instant app side, there are some restrictions. There are a lot of restrictions. You haven’t been installed, so you can’t access a lot of defaults. You can’t access external storage. Everything you do has to be in the foreground, you can’t have any background services. You have to use the new Android run-time permissions system.
Outside of that you actually only get to use some subset of Android run-time permissions. You have to handle what happens if someone says no, I don’t want to give you this permission. You can’t do push notifications, you can’t even get a persistent token for the user outside of this instant app session. You can’t hold onto anything they don’t want you to hold on to. You can’t make any calls to the HTTP services, it all has to be HTTPS. There’s a file size limit that sounds really scary, and it terrified me when I first did it because I have a lot of assets. It ended up not being a big major thing. We’ll get back to the file size thing in a bit.
Perspectives on Instant Apps
There are many benefits of instant apps with me as the PM and team lead of my team. I just let the user do what they want to do. I know I talked about this already, but this is vital to me. I have spent the past year working on what happens if someone lands on our mobile website and giving them an optimal mobile website experience. I don’t want someone to download 1.5 megabytes of HTML and then say go install my app, because the content’s right there, the answer to the question is right there. I want to give them that answer.
This lets me do that while also getting the benefits of the native code that I’ve been sitting on for years. The login flow in the instant apps is really cool, you have to use Google Smart Lock if you do login. Google Smart Lock lets you save passwords and authentication on the back end. You can do username and password, you can do Google login, but the really cool thing for me is I think 87 percent of Stack Overflow logins are Google accounts.
If someone opens up my instant app, they’re automatically logged in for the most part, which is pretty cool. I’m not actually trying to get people to install my app, I want them just to have the experience they want. There are some things that in my instant app if you try to do, it upsells you to install the app instead. I have a proven track record from my results that show me that really is helping drive more installs to my app even though that’s not my main goal.
With my dev hat on, I love the separation of concerns. I think all things that only talk to one thing should exist in one thing and shouldn’t go somewhere else. Instant apps require you to have separation of concerns. You’re going to end up doing modular code, and we’re going to have some diagrams in a bit, but when you separate out your code and you say, this is what this code does, this is what it doesn’t do, it helps.
You can test it easier; you can do unit tests easier, and you can do integration tests easier. There’s a lot of benefits to modularizing your code outside of just being able to do instant apps. Code reuse is a really nice thing.
I said about a year and a half ago, I got into the instant apps beta and the first pass we did was at a very old SDK and then I had to completely redo it to do it with the newer SDK. The version that was at an old SDK was a different branch. For a month and a half I had an instant app running at the same time as my installed app. If I changed the bug in one thing, I had to open up the other branch and change it. That was just something you have to always put in the back of your mind; it’s a hindrance. I’m adding this one thing, you have to remember to move it to this other place. Reusing code and not having to duplicate your own actions is really nice.
You get to use Dagger because you’re literally injecting things into places and having modules that depend on each other. It’s a really good excuse to actually do dependency injection. The key business objective difference for me is the flow for when someone clicks on a link to Stack Overflow is so drastically different. I get to show them the best experience the fastest way possible, versus the mobile website that we have that has that app banner. Why would you even click on that app banner unless you want to install my app? That’s the only purpose, it’s not to interact with this, because you could already interact with it. That mobile web banner, we actually have a lot of logistics around it of showing it, hiding it, and doing decay when they hit the X button and showing it three days later. I actually don’t show that banner on embedded web views.
If you’re in Twitter, and it uses its own web view because it does not use a cookie jar, but the web storage of the regular one; I don’t know if you’ve dismissed the banner, and I just want to be safe so I just show you the banner. There’s no way to even get to my app from the biggest social sharing endpoints. Now, you click on it and my app just shows up. Every single time it makes me giggle so much, I love it so much; it seems magical.
The main thing is instant apps reduce friction. They reduce friction when it comes to getting the user to actually do what they want to do. They reduce friction when it comes to logging in because it’s mostly automatic. They reduce friction when it comes to installation, there’s actually a lot of new Play Store APIs that do in-app, on demand, in-dialogue installation.
Even payments are frictionless. There’s a whole new payments API called Google Payments API that I’ll talk about in a bit, but it lets you use your own provider, like Stripe or Brain Tree, to use saved credit cards on Google accounts. There’s a lot of barriers to entry, just being completely taken down.
From the user perspective side, from someone interacting with your app, from someone clicking on a link, you have a whole new first time user experience to try to optimize. You can do anything you want to do with it, you can do a specific view of your app, you can do a branded thing for something, you can do whatever, but it gives you this new touchpoint with the user that’s your first attempt to delight them or have a nice interaction with them or not show them a popup.
Before we get into the actual specifics, all of this requires Android Studio 3, which is in Canary. I’m not going to say it’s stable, but it works. You can use it alongside Android Studio 2.3 and all of the stuff is first party in Android Studio 3.0.
I’m going to cut to the chase. The hardest part of all of this is how you think about your app. Your app goes from being a monolithic thing that has a front door and people come and go through it to being a bundle of features. I’m going to do a stark transition to something out of the docks.
In the example that I’m going to talk about, we only have one feature, but the point of this is instant app APK, to do multiple things, we’re going to call them features. They are limited user scope flows of trying to do a specific action. They also have a little helper, and that’s the base; that’s shared in all of your various instant apps.
TripIt is one of the instant apps launch partners, and they have instant apps for coming to a flight link, to a hotel link, or a reservation link. If you come in from all of those different entry points, you see drastically different stuff based on what they know about you. They all share one little base module of code between all of them.
The example we’re going to go into, only has one feature and one base, and this is titled “Instant app APK”, but your full installed app APK will end up being similar to this too.
Before and After
What’s in an app? My app Stack Exchange, you probably have participated on Stack Overflow at some point in your lives hopefully and no one’s shouted at you. We allow people to do a lot of things. The biggest 90% of the use cases is interacting with questions and answers. It’s someone who’s here to learn something, who’s here to ask something, who’s here to comment on something, who’s here to say, “This doesn’t make sense”, or who’s here to say, “This API got deprecated”.
The second biggest use case, which is our front door in the app, is for searching and browsing, it’s to find content. We have 170 now, communities of very drastically different information that you can learn and we try to give that to the user. The ideal experience for the Stack Exchange app is and always was for someone to sit on their couch and spend 30 minutes browsing around and seeing what they want to do.
The ending part is all of the actual high touch KPIs that don’t happen a lot but I have to have a lot of flows around them. It’s the creation actions, it’s asking a question, it’s adding an answer; it’s creating content. For me, each one of these could be their own instant app. I have just one instant app right now for the questions and answers, and I just have it for stackoverflow.com, not for our other communities; I’ll get into the specifics why.
There could be an instant app to browse the content. There could be an instant app to search, and there can be an instant app to add an answer. Right now in the instant app that I have, that’s one feature. If you click on a link it has a little popup come up that asks if you would you like to install the app. It very clearly and very easily instead of asking you to install the app, it could just launch the next instant app and put them right into that flow. It could use the next module of my app without installing the app.
Before Android instant apps, there was one big app module, two support, and dependencies. The app module includes everything. It has all of my functionality, it has the login, it has the signup, it has the analytics that go into those activities, and it has the parent base fragment that those activities all use that includes the analytics. I use MVVM everywhere; it has a lot of view models. It has a bunch of modules in it like Core, DB, UI, Utils, and API.
A lot of those are business application logic; some of those are functionality feature logic. My other two modules, based on what we’re going to talk about, it seems moot to even call them modules, but there’s two very small self contained things. There’s a markdown editor in our app. If you try to ask or add an answer, it has a little toolbar that comes above the onscreen keyboard and you can hit it to toggle bold or code or toggle whatever you want to toggle.
We have all of those handlers in there and the actual UI element that shows up the linear layout includes all those buttons and all of the unit tests around what happens when someone clicks on one of those. The third module that I have, is stackman, it’s our API module, I hate it so much. It uses Java Futures because we made it a very long time ago before I was an actual full-time Android dev, so there’s a lot of wrapping that goes around it. It has a lot of access to our custom API airing and rate limiting. What happens if our API goes down and the callback backs off throttle it gives us.
There’s a lot of business logic around just calling the API, that’s all contained in that module and it does a bunch of unit tests. The things you might see that isn’t here is I don’t have a lot of tests in my app module. I have functionality tests where I open up something and I scroll and make sure it doesn’t crash. For the most part, everything’s really tied together and I don’t have a lot of tests. I didn’t have a lot of tests before instant apps.
This is what we have now. That orange dashed box is both your installed app and your instant app. This orange dashed box includes two new modules but it’s actually going to include a third one that we’ll talk about in a second. It has the shared module, which is the base module that was in a Google Document. It’s where my installed app and my instant app and any other instant apps I make in the future, all get the code that they share. I called it shared, I’m not very creative.
It has a feature for Q&A, that has all of the logic for displaying a question and answer. We ask a question and then answer it directly underneath it. There’s a lot of recycler view stuff for loading them and for showing one answer, or for showing 20 answers.
For the actual full installed app, it’s the entire container; it’s all of the code in the app module, the code in the question and answer feature, the code in the shared library and all the other dependencies. For the instant app APK, it’s the shared library that we’re about to make, the feature that includes the code just for showing questions and answers, and then we have a third module that’s just a wrapper. You set a plugin type on it of com.android.instantapp and then that generates a build variant for assembling the instant app.
The instant app can have multiple features in it. It can have just one thing and then link to the other stuff or it can have all of them at the same time. There’s some file limitations and we’ll get into that. These three new modules are the actual net differences between the before and after.
What’s going to be in your shared library?
Everything that’s shared between the stuff. Which sounds simple, but you have to actually think through your app module. What is in my app module that is business metrics, and business goals? What is in my app module that is actual user facing functionality that I’m trying to do? For the most part, all of the stuff for our shared business logic your retrofit custom adapter, is going to be shared with all of the stuff that calls the network calls.
You can move it around. Shared external dependencies means Gradle imports basically. Anything that you are importing on your app module can be moved over to this library because it’s just a regular Android library. The thing that becomes a little difficult is your feature module can also have its own imports, but any time you’re adding a Gradle import to your feature module or to your app modules, you need to check if it is going to be shared. Say as much or as little as you like when it comes to the actual code because there is a file size limit that’s going to come up in a bit that I’ll talk about.
If I have three instant apps for the question and answer flow, for the search and for adding an answer, this shared library will be in every single one of them. If there’s anything that’s not in every single one of them, I’m wasting some space over the wire. It depends on what your code complexity for how you like to structure your architecture; you can have the base classes and it’s not too bad if your app module’s version of showing something and your instant apps version of showing something have their own fragment and then the fragments call something else in the background.
If it’s their own fragment and each is 800 lines and it’s the exact same methods, you don’t want to be doing that. You don’t want to be copy pasting code too much.
Let’s get into the actual flow. First, you make a new module. It’s a library; it’s not anything like fancy. When you make a new module, you get the choice between Android package, an Android library or an instant app feature on instant app APK. You just choose a library, it’s just a regular Android library. You’re just moving code over to this shared library.
The easiest ones to move over are support libraries. You just move them over from your app module into the shared library module because probably you’re going to be calling fragments in your application both times.
The next one is the harder one, there’s a lot of dread involved. You make a new feature module. It’s an actual module with a plugin type com.android.feature. Depending on how you have your UI set up, I have single activity but a bunch of different fragments that can come into it, so my feature module needs to have a single activity that can hold on to that fragment. You might not need to make a second activity.
The next thing is to copy paste the UI code. The recycler view adapters, the view models, for all of the stuff, just bring them all over. If you’re like me and you freak out about red error lines, disable Android Studio’s automatic build. We’re going to be in a bad place for a while.
For me, this was around a few weeks the first time I was doing it, the second time I was doing it, it was around 45 minutes. There’s a code lab that’ll help you get through the processes of it in around 30 minutes. There’s a lot of dread involved; there’s a lot of times you think you made everything break. Eventually, you will get through something.
In the feature module, we’re going to go through every single file one by one and we’re going to only look at the top of it. We’re going to look at the imports and just look for the red. There’s going to be a lot of easy first pass stuff where you’re importing classes that exist in your app module. For me, those were classes that lived in modules like Core or UI. For some crazy reason, I have my own entire rewrite of recycler view. It’s for a very specific reason, but that’s the pain of Android.
I had to bring my entire recycler view over into my shared library. All of the actual shared UI elements that the code is already modularized in a different thing, like Core or UI or API or something where you at one point knew that this isn’t your actual app logic. For ll of the files, we’re just going through the import section.
Now, you go through all of the files and you go through the actual code. There’s going to be a lot of code that is in two places, there’s going to be a lot of code that is in your feature module and is also in your app module. There’s going to be a lot of references to things that don’t exist in this feature. I had four different flows to get to the user’s profile page from that flow, I just stubbed every single one of them out. You have to do that for everything in every single file.
I’m the kind of developer that requires to see what’s happening. When I have a crash, someone tells me there’s a bug in my app, I want to see a repro because I don’t believe you. I need to see it with my own eyes and make sure that it actually happened and I’m always living in fear of my own code. I don’t have tests, so you can understand why I’m in fear of my own code. This was the hardest part because every single day I was moving stuff around and nothing compiled and I thought it would work and it turned out that I was using Java 8 Retro Lambda and I needed to move off the Java 8 stuff to this one. It became just a thing and it becomes hairy and you can go down a rabbit nest very quickly. If you just stick to stubbing everything out and trying to get to the point where things compile, it’s not too bad.
The hardest part about this is to not rewrite code. Don’t write any new code. You will see stuff that uses AsyncTasks and be so embarrassed, I don’t even want anyone to know that I did this at some point in my life, leave it. You’re here to get the code to compile again; if you start refactoring stuff, you usually end up doing nothing.
The first time that I did the instant apps integration, I was having a quiet summer so I let myself do whatever I wanted. There was also a major RX Java API endpoint change, but it wasn’t their actual one to two change, but there were things in the ether that I knew I was behind on so I dedicated myself to it. I had to delete that branch of code three times, just because I got nowhere, it didn’t compile, I didn’t know what was happening, I didn’t know what was my old code, I didn’t know what was my new code. I didn’t know what the thing was trying to do.
While you’re doing this, you’re going to be looking at a lot of old code, don’t rewrite it. Leave it exactly as it is, move it around into places, but don’t edit the contents outside of deleting it and saying, “I’m going to figure this out later.”
Don’t write any new abstractions. I wrote a lot of interfaces. I’ve been doing Java for a very long time, and I really like Java and I really like abstractions and interfaces. Don’t do that, because then you get in situations where you get confused about where this abstraction lives. Does it live in a shared library, does it live in a feature library or is this something that is made to communicate with the app module? It’s overthinking it for all of this. Just move code around, treat it like images. Move it around, move it somewhere else if you need to, and try to get the thing to compile.
Before Instant Apps, all I had was the app module, that was this monolithic thing that has every single thing on the planet. Now, the app module is still kind of monolithic, it has everything, but the main guts of looking at the question and answer is taken out of it.
For the app module, there’s a lot of cross dependencies here. The app module depends on the shared module, the Q&A feature depends on the shared module, and the app module and Q&A feature actually have some duplicated code in how they interact with the thing in the shared module. The thing in the shared module is my custom view that’s a post view that can show the question and answer. On the different two cases, I have an activity that holds a bunch of fragments or an activity that only holds this fragment.
There’s also another module that I mentioned that isn’t in this, but the com.android.instantapp is the thing that’s actually generating your instant app. It builds a build variant for your instant app. After the first time it launches, you should, if you do what I do, you run around, you scream, and you tell people and they all have you repeat what the actual benefit of this is, you say it really excitedly and they say, “Oh, so the thing you spent last year working on, people will actually see.”” I’ll say, “Yeah, it’s really exciting, be happy for me.” You should celebrate, it’s a really cool thing.
After you get the first thing to launch, you have a lot of decisions to make because we’re going to repeat all of that process for everything. For a link to anything in your activity that you stubbed out and you said, I’ll deal with this later, think about what you want to do with it. Think about if you want to put it in your feature. Think about if you want to make a new feature. Think about if it should only be available in your installed app. You have a lot of things that you can do. The hardest one is if you want to add it to this feature or if you want to make it into a new feature and remember, one instant app can have two features.
If you want to do that, you have to just flat out make a new module, copy paste the code over, and play the refactoring game all over again. Now that you have two modules, there’s some stuff in shared library that didn’t really need to be in shared because it’s not in the second module. Maybe you chunk out the shared module to be shared UI and shared Core. It’s just the same game as what we just did.
Next, let’s talk about install prompts, and getting people to actually install your app. There’s two different types: explicit and implicit.
An Explicit install is a button that actually says install. You can put it anywhere in the app, you can have it on the home screen of the app, you can have it in the navigation bar, you can do whatever you want to do with it. For my case, I don’t actually have any explicit buttons in the navigation or the app itself, but if you try to log in and you don’t have an account, it says, “Would you like to sign up, would you like to install to sign up?”
Implicit prompts are when the user tries to do something that they thought they could do because you share the same UI, the same look, and they can’t do it. You just give them a little popup, with a little explanation that what they are trying to do requires installing the app. You have to figure out what you want to do with them and just show the user the prompt when they need it, it’s not too bad.
For the instant apps actual API, there’s a class called instant apps, and it has two methods. One method returns a Boolean, it is instant app, and you can use this in your shared code. I don’t actually use this in my shared code, it felt weird for my shared code to depend on an instant apps class. I have this as a flag that I pass in when I call methods in my shared code, but it’s just to switch up the flow for what happens when someone tries to do something in the instant app versus in the installed app.
The second method is for the implicit installs that I just talked about. It shows an in-app dialogue Play Store and they can click install on it and it installs the app from the Play Store and then your app launches. It’s the fastest way to install an app ever. It’s really cool, it’s embedded Play Store inside of your app in a little dialogue just by calling the show install prompt method.
Code Reuse Is Good
The end goal of when you’re migrating your code over, when you’re changing your modules, when you’re decoupling your code, when you’re modularizing it, is heavy code reuse. You don’t want to be editing something once in two places, you want to use something once and it works in two places. You don’t want any duplicated code, you want separation of concerns, you want modularized code, and you want things that are with the things that they should be with, because that lets you do a lot of things. It lets you unit test them easier, it lets you do actual functionality tests on them, black box them saying, all of this stuff is stubbed out, but it actually is stubbed out, it’s not in this code. The end result should hopefully be a really nice module heavy code reuse package.
The stuff to think about in the context of instant apps outside of just doing the first instant app is, what is actually your wrapper? What’s your main activity, what’s your launch point into your application? I don’t mean this from the user flow side, although I do mean it for the user flow side too. What is the default application class that opens up in your app, what is the default activity? What does it do?
In my case, the default activity holds on to 17 different fragments and it has a navigation drawer and it can do this, and it can do that. In my app, in my instant app, it doesn’t do any of that. It holds on to a fragment and it can take the intent string and say, “They’re trying to look at this question, let me show this question.”
It’s a very drastic difference for the entry point of the app. If you do login, you have to do Google Smart Lock; Smart Lock lets you store username and password, it lets you store Google login information, and it lets you store login information from any service really. The really nice thing about the Smart Lock login is the first time someone comes to your instant app and they try to log in and they have the Google Smart Lock login happen, the next time they open up your instant app, even if it’s weeks or months later, they’re logged in automatically. They get a little banner that says their name, everything seems really cool, you can change the state to show whatever they can do now.
For physical payments, there’s a brand new API called Google Payment API. It is really cool. It is like the current API that exists, and it lets you access the credit cards that people have saved on their Google account, but you get to use your own processor. You get to use Stripe, you get to use Brain Tree; you get to use whatever you want and actually connect it with the APIs that you would normally have.
The hardest actual step is that everything is modular so all of the permissions are too. If someone doesn’t want to give you a permission for something, you can’t crash. You have to actually interact and do what they expect it to do, just degraded.
If we talk about what the actual logistics of the world around this are, when it comes to launching your instant app, you’re going to build an instant app APK, it’s very similar to building a regular APK. You upload it on the Google Play Store, it’s very similar to uploading a regular app; it has the same kind of three tiers on the Play Store, so it’s not too bad. When it comes to the actual, connecting of how people are going to end up in it, there’s a difference between launching it by calling the intent manager and the activity manager on your console and someone clicking on the link.
You need to prove that you actually own the app and the link, you do that via Google App Links. The website https://stackoverflow.com gives the permission, and handles all URLs to my app. My app’s name is com.stackexchange.marvin, the paranoid android, and then the certificates for the APK, the production APK and then the one for when I build it on my own computer so I can test. The JSON file is checked on app install.
On your Android manifest side, you have an intent filter that says autoverify equals true, and that means that for this intent filter, go through every single host and check that the host actually has given us permission. I was really worried about this part. I was worried it was going to be a whole thing with the web guys and they say oh, you want a static file, that’s super easy. Let’s just take care of it. It’s not too big of a thing to worry about, but you need to have this to actually do an instant app.
It’s all about launching really quick apps, which means you can’t have a lot of bloat. When it comes to something going over the wire, in my initial demo I click on a link to stackoverflow.com and that loading icon showed up, everything that’s transferring through that wire needs to be under four megabytes. That sounds really small, but remember, this is one specific part of your app, it’s a very limited use case of your app. I’m at 2.7 megabytes and I thought I was going to hit four megabytes. I’m not even using ProGuard, it’s not too hard to do this, it’s just something you need to be aware of.
One caveat is this is checked when you’re uploading your APK to the Play Store, so you will know immediately if it’s too big. The second thing, is that these APKs use the new version two signing method, so they have multiple things inside them that have their own signatures. When it comes to those multiple things, the APK includes the feature, at least one, and the base.
For my case, that’s the shared library and then the Q&A feature, it can include multiple features. When it comes to it, the size over the wire is that entire bundle. It’s the feature and the shared library that goes with it. That’s why we can’t have too much bloat in a shared library. The other caveat, is that if you’re doing multiple instant apps, if someone is interacting with your first instant app and they click on a link to something that opens up in a second instant app.
For my case, when I eventually add answer or ask question as an instant app, when that second instant app is loading the four megabytes doesn’t include the base, because the base is already downloaded. It’s the bundle in general, the bundle includes the shared library and if they’ve already loaded the bundle once, that shared library’s not going to get downloaded again.
That doesn’t mean make your past first point interactions really heavy, because those interaction points probably have their own side entry too, so they need to be less than four megabytes, but you can keep that in mind. When it comes to launching and thinking about the business perspectives, the biggest thing is, use a different analytics key. The people are going to interact differently, the user flows are different, they’re coming to do different stuff, they’re coming from different entry points.
The entire flow of this is different so don’t just use the exact same analytics that you’re using, use a new key to differentiate between what you’re doing. You can use Google Analytics for Fire Base to give a lot of actual actions. You can store what happened, and it’s part of the Google Analytics, so it’s not too bad.
When you publish it in the Play Store, you just upload the instant app APK, and there’s three tiers you can do. I don’t know what they’re called now, but like dev, staging and prod, but it’s not that. For people like me who are in charge of the entire perspective of mobile, web and native app and we want to figure out cross product KPIs. When you’re publishing an instant app, you can set a percentage of how many people when they click on a link are going to go back to your mobile website. You can actually test the different flows, if you’re a payment app or if the final endpoint is paying for something, you can check the funnels of someone buying on mobile web versus buying on native app all via the instant app just by modifying this mobile web pullback amount.
Building an instant app is not building a new app. It is a mindset shift. The hardest part about it is thinking about your app as a bundle of features and decomposing your app into what those features are and what the shared library is.
The goal of an instant app is to help your user do something, the goal of an instant app is not to get your app installs. It’s proven to help your app get installs, but they’re here to do something, they didn’t open up the door and say, what’s going on, what are we cooking for dinner, who’s hanging out here? They open up the door to come to a specific thing and look at it and get something and do something with it. Help them do that, not focus on getting app installs.
I know that sounds really worrisome because we’re app developers and install numbers matter a lot, but this is really changing what the focus is for my team in particular. My focus is no longer getting installs and session numbers from my app because the session numbers from my app no longer correspond to the installs. It’s focusing on, what the user wants to do, and helping him get there.
Think about your use cases. What do people want to do? How does your codebase split up into sections? Do you already have some stuff structured to be split up? Have that in the back of your head. You can modularize your code any time you want. I have a lot of tests now because this lets me do this. I love separation of concerns and modularizing your code. You don’t need to do this for instant apps, you don’t even need to wait until something is going to be used in an instant app feature to modularize it. You can just separate out the code.
I love code labs. There’s a code lab called Build your First Android instant app. It takes you through the process of having an application that has a little memory puzzle game and separating it out into shared library and then having a feature module and then launching the instant app.
There’s a lot of, verbiage where it talks about the concept of apps as features. You should be able to like, skip through that one now because you know it. It’s really fun. Try to do that if you don’t have your own code to work on this. Even if you don’t think you want to build an instant app, modularize the code, it’s really fun.
About the content
This talk was delivered live in July 2017 at 360 AnDev. The video was recorded, produced, and transcribed by Realm, and is published here with the permission of the conference organizers.