Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Ben Weiss - Migrating_from_installed_to_instant_app - a_retrospective
Search
droidcon Berlin
July 17, 2018
Programming
0
69
Ben Weiss - Migrating_from_installed_to_instant_app - a_retrospective
droidcon Berlin
July 17, 2018
Tweet
Share
More Decks by droidcon Berlin
See All by droidcon Berlin
Jon Markoff - Best practice for apps
droidcon_berlin_2018
0
140
Jon Markoff - Voice in the enterprise
droidcon_berlin_2018
0
47
Michael Jess - Enabling enterprise mobility with SAP
droidcon_berlin_2018
0
74
Ronen Sabag - Lean async code with Kotlin’s coroutines
droidcon_berlin_2018
0
37
Boris Farber & Nikita Kozlov - The_Build_Side_of_Android_App
droidcon_berlin_2018
0
150
Zan Markan - The state of Kotlin
droidcon_berlin_2018
0
48
Miquel Beltran - No More □ (tofu) Mastering Emoji on Android
droidcon_berlin_2018
0
98
Laurent Gasser & Jeremy Rochot - Sharing a success story - A low cost, Customer driven and co-developed Android EMM
droidcon_berlin_2018
0
140
Hoi Lam - Adding ML Kit to Android Things And some TensorFlow things
droidcon_berlin_2018
1
150
Other Decks in Programming
See All in Programming
Embedding it into Ruby code
soutaro
2
330
Direct Style Effect Systems The Print[A] ExampleA Comprehension Aid
philipschwarz
PRO
0
410
WinActorの勉強を継続する方法
tamai_63
0
130
スタックトレース始めてみた
kuro_kurorrr
5
1.1k
Runtime Objects in Rust
mitsuhiko
0
220
TypeScriptの型とパフォーマンス (TSKaigi 2024)
ypresto
14
4.6k
The Design of Everyday APIs - PyCon 2024
roguelynn
1
190
Prepare for Jakarta EE 11 - Performance and Developer Productivity
ivargrimstad
0
300
The Cutting Edge Of Versioning (LambdaConf 2024)
chriskrycho
0
250
TypeScript Custom GitHub Action Development Tips
peaceiris
2
500
TCAとKMPを用いた新規動画配信アプリ 「ABEMA Live」の設計
tomu28
2
140
Try creating your own orderedmap
kazamori
1
280
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
74
8.3k
The Power of CSS Pseudo Elements
geoffreycrofte
62
5k
A better future with KSS
kneath
231
16k
Designing with Data
zakiwarfel
96
4.8k
Building Better People: How to give real-time feedback that sticks.
wjessup
356
18k
The World Runs on Bad Software
bkeepers
PRO
61
6.7k
Robots, Beer and Maslow
schacon
PRO
155
8k
Git: the NoSQL Database
bkeepers
PRO
423
63k
Making the Leap to Tech Lead
cromwellryan
125
8.6k
Being A Developer After 40
akosma
67
580k
The Brand Is Dead. Long Live the Brand.
mthomps
49
30k
Scaling GitHub
holman
457
140k
Transcript
Installed → Instant A retrospective Ben Weiss @keyboardsurfer & Beyond
DroidCon Berlin - 2018
Google Play Instant DroidCon Berlin - 2018
Discovering an app DroidCon Berlin - 2018
Discovering an app Use Install Find DroidCon Berlin - 2018
With Google Play Instant DroidCon Berlin - 2018
> 1b devices DroidCon Berlin - 2018
Requirements DroidCon Berlin - 2018
Lollipop DroidCon Berlin - 2018
Android Studio 3.0+ • Instant Apps SDK • Gradle plugins
◦ com.android.feature ◦ com.android.instantapp • App Links Assistant • Emulator support • Refactoring tool DroidCon Berlin - 2018
4 MB < DroidCon Berlin - 2018
Migrating a real app DroidCon Berlin - 2018
Topeka DroidCon Berlin - 2018
A fun to play quiz Available on GitHub googlesamples/android-topeka Topeka
DroidCon Berlin - 2018
Topeka | UI DroidCon Berlin - 2018
Topeka | Development timeline now Sept 2014 First commit May
2015 Published to GitHub Transitions July 2015 Sept 2015 minSdkVersion 16 Oct 2015 minSdkVersion 14 Kotlin May 2017 DroidCon Berlin - 2018
Topeka | Now But how DroidCon Berlin - 2018
g.co/instantapps DroidCon Berlin - 2018
Topeka | TODO Size < 4MB Not URL addressable Manual
login ⤫ ⤫ ⤫ DroidCon Berlin - 2018
DroidCon Berlin - 2018
SmartLock API Automatically sign in users Less friction Faster access
to content DroidCon Berlin - 2018
SmartLock API Save Retrieve Activity Result DroidCon Berlin - 2018
CredentialsHelper.kt: fun Context.apiClient() = Credentials.getClient(this) apiClient().request() apiClient().save(playerCredentials) DroidCon Berlin -
2018
CredentialsHelper.kt: fun Activity.onSmartLockResult( requestCode: Int, resultCode: Int, data: Intent?, success:
(Player) -> Unit, failure: () -> Unit) DroidCon Berlin - 2018
CredentialsHelper.kt: fun Activity.requestLogin(success: (Player) -> Unit) fun Context.logout() DroidCon Berlin
- 2018
interface Login { fun loginPlayer(activity: Activity, onSuccess: (Player) -> Unit)
fun savePlayer(activity: Activity, player: Player, onSuccess: () -> Unit) } object DefaultLogin : Login // used within the app object TestLogin : Login // used for testing DroidCon Berlin - 2018
Topeka | TODO Not URL addressable Manual login ⤫ ⤫
✓ Size < 4MB ⤫ DroidCon Berlin - 2018
nytimes.com/crosswords URL Addressable DroidCon Berlin - 2018
<activity> <intent-filter android:autoVerify="true"> </intent-filter> </activity> <data android:scheme="http" /> <data android:scheme="https"
/> <data android:host="topeka.instantappsample.com" /> <data android:path="/signin" /> DroidCon Berlin - 2018
Intent(Action.VIEW, QuizActivity.class::java) .apply { putExtra(Category.TAG, category.id) val start = Intent(Intent.ACTION_VIEW,
myURL) .addCategory(Intent.CATEGORY_DEFAULT) .addCategory(Intent.CATEGORY_BROWSABLE) intent.`package` = context.packageName DroidCon Berlin - 2018
const val URL_BASE = "mybaseUrl" const val URL_SIGNIN = "$URL_BASE/signin"
const val URL_CATEGORIES = "$URL_BASE/categories" const val URL_QUIZ_BASE = "$URL_BASE/quiz/" // append category id DroidCon Berlin - 2018
Topeka | TODO Not URL addressable Manual login ⤫ ✓
✓ Size < 4MB ⤫ DroidCon Berlin - 2018
Gradle Plugins com.android.application DroidCon Berlin - 2018
Gradle Plugins com.android.instantapp DroidCon Berlin - 2018
Gradle Plugins com.android.feature application → aar instantapp → apk DroidCon
Berlin - 2018
app Create new modules settings.gradle: include ':base', ':installed', ':instant' base
instant installed apk aar DroidCon Berlin - 2018
Topeka | TODO Not URL addressable Manual login ✓ ✓
Size < 4MB ⤫ DroidCon Berlin - 2018
Feature module shuffle base quiz categories instant apk installed aar
DroidCon Berlin - 2018
s://commons.wikimedia.org/wiki/File:Spaghetti_al_Pomodoro.jpg
Feature module shuffle | base Shared code • Included dependencies
◦ api • Utilities • Model • Data layer DroidCon Berlin - 2018
Feature module shuffle | base Shared resources • colors •
themes • styles • drawables • strings • transitions DroidCon Berlin - 2018
Feature module shuffle | base Package name com.google.samples.apps.topeka.base.R as RBase
• Every dependent import has to change DroidCon Berlin - 2018 • Kotlin enables import aliasing
Feature module shuffle | others • Controllers • UI (custom
views) • Tests • Separate AndroidManifest • Drawables / assets • Package name changes DroidCon Berlin - 2018
Topeka | TODO Not URL addressable Manual login ✓ ✓
Size < 4MB ⤫ DroidCon Berlin - 2018
ConfigurationApks Screen Density User Language Processor Architecture DroidCon Berlin -
2018
ConfigurationApks res/ drawable-mdpi drawable-hdpi drawable-xhdpi drawable-xxhdpi drawable-xxxhdpi Base base.apk base-drawable-mdpi.apk
base-drawable-hdpi.apk base-drawable-xhdpi.apk base-drawable-xxhdpi.apk base-drawable-xxxhdpi.apk DroidCon Berlin - 2018
ConfigurationApks base.apk quiz.apk categories.apk instant.zip ldpi mdpi hdpi xhdpi xxhdpi
xxxhdpi ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi DroidCon Berlin - 2018
build.gradle: // feature modules flavorDimensions 'delivery' DroidCon Berlin - 2018
build.gradle: // feature modules productFlavors { installed { dimension 'delivery'
} ... } DroidCon Berlin - 2018
build.gradle: // feature modules productFlavors { ... instant { dimension
'delivery' minSdkVersion rootProject.minSdkInstant } } DroidCon Berlin - 2018
build.gradle: // installed app module defaultConfig { missingDimensionStrategy 'delivery', 'installed'
} DroidCon Berlin - 2018
build.gradle: // instant app module defaultConfig { missingDimensionStrategy 'delivery', 'instant'
} DroidCon Berlin - 2018
Topeka | TODO Not URL addressable Manual login ✓ ✓
✓ Size < 4MB ⤫ DroidCon Berlin - 2018
Bonus Round | Proguard Keep API surfaces intact DroidCon Berlin
- 2018
Takeaways Prerequisites first URLs, SmartLock, Restricted APIs, Permissions Refactor one
feature at a time Apply new plugins Size constraints DroidCon Berlin - 2018
Next Steps Link to domain using Android App Links Upload
to the Play Store Android App Bundle & Dynamic Delivery DroidCon Berlin - 2018
DroidCon Berlin - 2018
DroidCon Berlin - 2018
DroidCon Berlin - 2018
DroidCon Berlin - 2018 g.co/androidappbundle
DroidCon Berlin - 2018 master.apk ch.apk de.apk en.apk es.apk it.apk
pl.apk x86.apk armeabi.apk mips.apk drawable-ldpi.apk drawable-hdpi.apk drawable-mdpi.apk drawable-xhdpi.apk drawable-xxxhdpi.apk drawable-xxhdpi.apk
DroidCon Berlin - 2018 de.apk x86.apk drawable-xxxhdpi.apk master.apk
DroidCon Berlin - 2018 aab 4.2 MB apk 8.6 MB
com.android.application com.android.library com.android.dynamic-feature Modular Development DroidCon Berlin - 2018
Modular Development Core com.android.application app -> HomeActivity & few resources
com.android.library base -> most shared code & resources external dependencies search -> search code & resources DroidCon Berlin - 2018
Modular Development Dynamic Feature Modules com.android.dynamic-feature Separable Activity & local
resources designernews dribbble about DroidCon Berlin - 2018
shared search bypass DroidCon Berlin - 2018 com.android.library about designer
news dribbble app com.android.application com.android.dynamic-feature
Google Play Core API Enables dynamic delivery through the Google
Play Store Request modules Delete modules Immediately or deferred DroidCon Berlin - 2018
PlayCore API: Set up override fun onCreate(savedInstanceState: Bundle?) { ...
manager = SplitInstallManagerFactory.create(this) btn.setOnClickListener { install("dribbble") } } DroidCon Berlin - 2018
PlayCore API: Handle modules that are already installed fun install(moduleName:
String) { if (manager.installedModules .contains(moduleName)) { onSuccessfulLoad(name) return } ... DroidCon Berlin - 2018
PlayCore API: Request installation ... val request = SplitInstallRequest.newBuilder() .addModule(moduleName)
.build() manager.startInstall(request) } DroidCon Berlin - 2018
PlayCore API: Handle results private fun onSuccessfulLoad(moduleName: String) { ...
Intent().setClassName(packageName, className) .also { startActivity(it) } ... } DroidCon Berlin - 2018
Optimized APK for each device Upload an Android App Bundle
DroidCon Berlin - 2018
Optimized APK for each device Upload an Android App Bundle
Dynamic Delivery by Google Play DroidCon Berlin - 2018
Takeaways You can release an .aab today faster delivery ==
happier users Map out before you modularize Dynamic Delivery can be added at any point But still: Work one feature at a time DroidCon Berlin - 2018
Source Code: github.com/googlesamples/android-topeka github.com/nickbutcher/plaid Samples: github.com/googlesamples/android-instant-apps github.com/googlesamples/android-dynamic-features Blog: Enabling ProGuard
in an Android Instant App Docs: g.co/InstantApps g.co/AndroidAppBundle Resources DroidCon Berlin - 2018
Thank you! Ben Weiss @keyboardsurfer DroidCon Berlin - 2018
Questions? Ben Weiss @keyboardsurfer DroidCon Berlin - 2018