Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Android Instant Apps

Introduction to Android Instant Apps

Android Instant Apps are the new kid in the large town of Android-city. The promise behind it is quite simple and groundbreaking at the same time: running native Android apps instantly on your device, without installation.

In this session we will first introduce this evolution in app sharing and discovery mostly from a user perspective. Secondly, we will discover how, as a developer, you can build an Android Instant Apps and deliver this new experience frictionless to all of your users.

Cyril Mottier

October 20, 2017
Tweet

More Decks by Cyril Mottier

Other Decks in Programming

Transcript

  1. Introduction to Android
    Instant Apps
    by Cyril Mottier

    View Slide

  2. View Slide

  3. >

    View Slide

  4. >
    >

    View Slide

  5. > > >

    View Slide

  6. Find Install Start Setup Use
    Installing & using a mobile app is a
    long and steep path

    View Slide

  7. Reduce friction
    as much as possible

    View Slide

  8. Instant apps
    Native apps, without installation

    View Slide

  9. View Slide

  10. >

    View Slide

  11. >
    >

    View Slide

  12. You may only need 10% of an app’s features
    So why download 100%?

    View Slide

  13. Application

    View Slide

  14. Application
    Feature 1 Feature 2 Feature 3
    Common

    View Slide

  15. The build output now depends
    on the targeted run mode

    View Slide

  16. installable.apk
    Feature 1
    Feature 2 Feature 3
    Common

    View Slide

  17. instant_app.zip
    Feature 1
    APK
    Feature 2
    APK
    Feature 3
    APK
    Base APK

    View Slide

  18. What about the
    on-device behaviour?

    View Slide

  19. Installable app

    View Slide

  20. Feature 1
    Feature 2 Feature 3
    Base
    Installable app

    View Slide

  21. Instant app

    View Slide

  22. Feature 1
    Base
    Instant app
    Using feature 1

    View Slide

  23. Feature 2
    Base
    Instant app
    Using feature 2

    View Slide

  24. Feature 1
    Base
    Instant app
    Using feature 1 then 2

    View Slide

  25. Feature 1
    Feature 2
    Base
    Instant app
    Using feature 1 then 2

    View Slide

  26. Feature 1
    Feature 2 Feature 3
    Base
    Instant app
    Using all features

    View Slide

  27. Lollipop+

    View Slide

  28. Android Studio 3.0+
    with Instant Apps Development SDK

    View Slide

  29. Runtime permissions
    introduced in Android 6.0 (API level 23)

    View Slide

  30. App links
    Associate your app with your domain

    View Slide







  31. android:host="${host}"
    android:path="/licenses" />

    android:autoVerify="true"

    View Slide







  32. android:host="${host}"
    android:path="/licenses" />

    android:autoVerify="true"

    View Slide







  33. android:host="${host}"
    android:path="/licenses" />

    android:autoVerify="true"

    View Slide

  34. https:///.well-known/assetlinks.json

    View Slide

  35. https:///.well-known/assetlinks.json
    [
    {
    "relation": [
    "delegate_permission/common.handle_all_urls"
    ],
    "target": {
    "namespace": "android_app",
    "package_name": "com.gdgnantes.devfest.android",
    "sha256_cert_fingerprints": [
    "1A:24:9C:B5:69:5F:B5:21:CD:80:45:7A:06:20:C5:78:DB:
    07:A8:CA:A0:8F:E9:47:B9:F6:A5:60:6B:78:DB:32"
    ]
    }
    }
    ]

    View Slide

  36. https:///.well-known/assetlinks.json
    [
    {
    "relation": [
    "delegate_permission/common.handle_all_urls"
    ],
    "target": {
    "namespace": "android_app",
    "package_name": "com.gdgnantes.devfest.android",
    "sha256_cert_fingerprints": [
    "1A:24:9C:B5:69:5F:B5:21:CD:80:45:7A:06:20:C5:78:DB:
    07:A8:CA:A0:8F:E9:47:B9:F6:A5:60:6B:78:DB:32"
    ]
    }
    }
    ]
    "relation": [
    "delegate_permission/common.handle_all_urls"
    ]

    View Slide

  37. https:///.well-known/assetlinks.json
    [
    {
    "relation": [
    "delegate_permission/common.handle_all_urls"
    ],
    "target": {
    "namespace": "android_app",
    "package_name": "com.gdgnantes.devfest.android",
    "sha256_cert_fingerprints": [
    "1A:24:9C:B5:69:5F:B5:21:CD:80:45:7A:06:20:C5:78:DB:
    07:A8:CA:A0:8F:E9:47:B9:F6:A5:60:6B:78:DB:32"
    ]
    }
    }
    ]
    "namespace": "android_app"
    "target": {
    }

    View Slide

  38. https:///.well-known/assetlinks.json
    [
    {
    "relation": [
    "delegate_permission/common.handle_all_urls"
    ],
    "target": {
    "namespace": "android_app",
    "package_name": "com.gdgnantes.devfest.android",
    "sha256_cert_fingerprints": [
    "1A:24:9C:B5:69:5F:B5:21:CD:80:45:7A:06:20:C5:78:DB:
    07:A8:CA:A0:8F:E9:47:B9:F6:A5:60:6B:78:DB:32"
    ]
    }
    }
    ]
    "package_name": "com.gdgnantes.devfest.android"
    "target": {
    }

    View Slide

  39. https:///.well-known/assetlinks.json
    [
    {
    "relation": [
    "delegate_permission/common.handle_all_urls"
    ],
    "target": {
    "namespace": "android_app",
    "package_name": "com.gdgnantes.devfest.android",
    "sha256_cert_fingerprints": [
    "1A:24:9C:B5:69:5F:B5:21:CD:80:45:7A:06:20:C5:78:DB:
    07:A8:CA:A0:8F:E9:47:B9:F6:A5:60:6B:78:DB:32"
    ]
    }
    }
    ]
    "sha256_cert_fingerprints": [
    "1A:24:9C:B5:69:5F:B5:21:CD:80:45:7A:06:20:C5:78:DB:
    07:A8:CA:A0:8F:E9:47:B9:F6:A5:60:6B:78:DB:32"
    ]
    "target": {
    }

    View Slide

  40. https:///.well-known/assetlinks.json
    [
    {
    "relation": [
    "delegate_permission/common.handle_all_urls"
    ],
    "target": {
    "namespace": "android_app",
    "package_name": "com.gdgnantes.devfest.android",
    "sha256_cert_fingerprints": [
    "1A:24:9C:B5:69:5F:B5:21:CD:80:45:7A:06:20:C5:78:DB:
    07:A8:CA:A0:8F:E9:47:B9:F6:A5:60:6B:78:DB:32"
    ]
    }
    }
    ]

    View Slide

  41. Modularise your code
    Break the app into features

    View Slide

  42. Pointing out
    features

    View Slide

  43. Licenses
    :features:licenses module
    Installable app
    :app module
    About
    :features:about module

    View Slide

  44. What about the base APK?
    contains code/resources used in all modules

    View Slide

  45. Application icon
    Custom font management
    Common styles, dimens, colors, …
    Base Activity/Fragment implementation
    Utilities
    etc.
    What about the base APK?
    contains code/resources used in all modules

    View Slide

  46. Modularize
    action in Android Studio

    View Slide

  47. ./settings.gradle
    include ':app',
    ':features:about',
    ':features:base',
    ':features:licenses',
    ':instant'

    View Slide

  48. include ':app',
    ':features:about',
    ':features:base',
    ':features:licenses',
    ':instant'
    ./settings.gradle
    ':app'

    View Slide

  49. include ':app',
    ':features:about',
    ':features:base',
    ':features:licenses',
    ':instant'
    ':features:base'
    ./settings.gradle

    View Slide

  50. include ':app',
    ':features:about',
    ':features:base',
    ':features:licenses',
    ':instant'
    ':features:about'
    ./settings.gradle

    View Slide

  51. include ':app',
    ':features:about',
    ':features:base',
    ':features:licenses',
    ':instant'
    ':instant'
    ./settings.gradle

    View Slide

  52. apply plugin: 'com.android.feature'
    android {
    //...
    baseFeature true
    }
    dependencies {
    application project(':app')
    feature project(':features:about')
    feature project(':features:licenses')
    }
    ./features/base/build.gradle

    View Slide

  53. apply plugin: 'com.android.feature'
    android {
    //...
    baseFeature true
    }
    dependencies {
    application project(':app')
    feature project(':features:about')
    feature project(':features:licenses')
    }
    ./features/base/build.gradle
    apply plugin: 'com.android.feature'

    View Slide

  54. apply plugin: 'com.android.feature'
    android {
    //...
    baseFeature true
    }
    dependencies {
    application project(':app')
    feature project(':features:about')
    feature project(':features:licenses')
    }
    ./features/base/build.gradle
    baseFeature true

    View Slide

  55. apply plugin: 'com.android.feature'
    android {
    //...
    baseFeature true
    }
    dependencies {
    application project(':app')
    feature project(':features:about')
    feature project(':features:licenses')
    }
    ./features/base/build.gradle
    application project(':app')
    feature project(':features:about')
    feature project(':features:licenses')

    View Slide

  56. apply plugin: 'com.android.feature'
    android {
    //...
    baseFeature true
    }
    dependencies {
    application project(':app')
    feature project(':features:about')
    feature project(':features:licenses')
    }
    ./features/base/build.gradle

    View Slide

  57. apply plugin: 'com.android.feature'
    //...
    dependencies {
    implementation project(':features:base')
    }
    ./features/about/build.gradle

    View Slide

  58. apply plugin: 'com.android.application'
    //...
    dependencies {
    implementation project(':features:base')
    implementation project(':features:about')
    implementation project(':features:licenses')
    }
    ./app/build.gradle

    View Slide

  59. apply plugin: ‘com.android.instantapp'
    //...
    dependencies {
    implementation project(':features:base')
    implementation project(':features:about')
    implementation project(':features:licenses')
    }
    ./instant/build.gradle

    View Slide

  60. apply plugin: ‘com.android.instantapp'
    //...
    dependencies {
    implementation project(':features:base')
    implementation project(':features:about')
    implementation project(':features:licenses')
    }
    ./instant/build.gradle
    apply plugin: ‘com.android.instantapp'

    View Slide

  61. apply plugin: ‘com.android.instantapp'
    //...
    dependencies {
    implementation project(':features:base')
    implementation project(':features:about')
    implementation project(':features:licenses')
    }
    ./instant/build.gradle

    View Slide

  62. where
    Function returning the binary size of
    Total download bundle binary size

    View Slide

  63. where
    Function returning the binary size of
    Maximum download bundle binary size

    View Slide

  64. Maximum download bundle size
    (i.e. that weird “ ” constant)

    View Slide

  65. During
    development

    Maximum download bundle size
    (i.e. that weird “ ” constant)

    View Slide

  66. Play Store
    dev tracks
    10MB
    During
    development

    Maximum download bundle size
    (i.e. that weird “ ” constant)

    View Slide

  67. 4MB
    Play Store
    production
    Play Store
    dev tracks
    10MB
    During
    development

    Maximum download bundle size
    (i.e. that weird “ ” constant)

    View Slide

  68. The smaller, the better
    (not specific to Android only)

    View Slide

  69. Slim down your
    APK size

    View Slide

  70. Slim down your
    APK size
    Resource shrinking

    View Slide

  71. Slim down your
    APK size Code minification
    Resource shrinking

    View Slide

  72. Slim down your
    APK size Code minification
    Vector graphics
    Resource shrinking

    View Slide

  73. Slim down your
    APK size Code minification
    Vector graphics
    Resource shrinking

    View Slide

  74. Slim down your
    APK size
    Dependencies reduction
    Code minification
    Vector graphics
    Resource shrinking
    Downloadable fonts
    Resources de-duplication
    Remote fetching
    Images optimisation
    WebP format
    Granular dependencies
    Density bucket removal
    Native code architecture removal
    Wear 2.0 APK distribution
    Sparse translation elimination
    Version collapsing

    View Slide

  75. APK Analyser

    View Slide

  76. APK Analyser

    View Slide

  77. Still not enough?
    Configuration split to the rescue

    View Slide

  78. android {
    //...
    generatePureSplits true
    splits {
    abi { enable true }
    density { enable true }
    language {
    enable true
    include "en", "fr"
    }
    }
    }
    ./base.build.gradle

    View Slide

  79. Installation
    prompts

    View Slide

  80. dependencies {
    //...
    implementation 'com.google.android.instantapps:instantapps:1.1.0'
    }
    ./features/base/build.gradle

    View Slide

  81. if (InstantApps.isInstantApp(this)) {
    val postInstallIntent = MainActivity.newIntent()
    InstantApps.showInstallPrompt(this, postInstallIntent,
    INSTALL_PROMPT_REQUEST_CODE, "Referrer")
    }

    View Slide

  82. Keep user state
    after app installation

    View Slide

  83. Cookie API
    // Instant app
    with(packageManager) {
    if (cookie.size <= instantAppCookieMaxBytes) {
    updateInstantAppCookie(cookie)
    }
    }

    View Slide

  84. // Installable app
    val cookie = packageManager.instantAppCookie
    // ... (i.e. restore user data)
    packageManager.clearInstantAppCookie()
    Cookie API

    View Slide

  85. Instant App Data
    dependencies {
    //...
    implementation 'com.google.android.gms:play-services-instantapps:11.4.2'
    }
    ./features/base/build.gradle

    View Slide

  86. Instant App Data
    val client = InstantApps.getInstantAppsClient(this)
    val fileTask = client.instantAppData
    fileTask
    .addOnCompleteListener { readData(it.result) }
    .addOnFailureListener { handleException(it) }

    View Slide

  87. Instant App Data
    Shared Preferences
    getFilesDir()
    getDir(String, int)
    Databases
    ParcelFileDescriptor
    to the caller's Instant App's data

    View Slide

  88. Instant Apps in the real world
    aka the pros and cons

    View Slide

  89. VS
    Instant
    apps
    Progressive
    Web apps

    View Slide

  90. Thank you!
    cyrilmottier.com
    @cyrilmottier

    View Slide