CINXE.COM

<!doctype html><html lang="en"><head><title data-rh="true">Google Santa Tracker — moving to an Android App Bundle | by Chris Banes | Android Developers | Medium</title><meta data-rh="true" charset="utf-8"/><meta data-rh="true" name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,maximum-scale=1"/><meta data-rh="true" name="theme-color" content="#000000"/><meta data-rh="true" name="twitter:app:name:iphone" content="Medium"/><meta data-rh="true" name="twitter:app:id:iphone" content="828256236"/><meta data-rh="true" property="al:ios:app_name" content="Medium"/><meta data-rh="true" property="al:ios:app_store_id" content="828256236"/><meta data-rh="true" property="al:android:package" content="com.medium.reader"/><meta data-rh="true" property="fb:app_id" content="542599432471018"/><meta data-rh="true" property="og:site_name" content="Medium"/><meta data-rh="true" property="og:type" content="article"/><meta data-rh="true" property="article:published_time" content="2020-10-15T16:19:50.494Z"/><meta data-rh="true" name="title" content="Google Santa Tracker — moving to an Android App Bundle | by Chris Banes | Android Developers | Medium"/><meta data-rh="true" property="og:title" content="Google Santa Tracker — Moving to an Android App Bundle"/><meta data-rh="true" property="al:android:url" content="medium://p/dde180716096"/><meta data-rh="true" property="al:ios:url" content="medium://p/dde180716096"/><meta data-rh="true" property="al:android:app_name" content="Medium"/><meta data-rh="true" name="description" content="This post is the first in the series which explores the improvements made to the Google Santa Tracker Android app for 2018. Santa Tracker is an app which Google releases every year, allowing users to…"/><meta data-rh="true" property="og:description" content="This post is the first in the series which explores the improvements made to the Google Santa Tracker Android app for 2018."/><meta data-rh="true" property="og:url" content="https://medium.com/androiddevelopers/google-santa-tracker-moving-to-an-android-app-bundle-dde180716096"/><meta data-rh="true" property="al:web:url" content="https://medium.com/androiddevelopers/google-santa-tracker-moving-to-an-android-app-bundle-dde180716096"/><meta data-rh="true" property="og:image" content="https://miro.medium.com/v2/resize:fit:1200/1*ksxyyNT2V-A2N626DZ9D7A.png"/><meta data-rh="true" property="article:author" content="https://chrisbanes.medium.com"/><meta data-rh="true" name="author" content="Chris Banes"/><meta data-rh="true" name="robots" content="index,noarchive,follow,max-image-preview:large"/><meta data-rh="true" name="referrer" content="unsafe-url"/><meta data-rh="true" property="twitter:title" content="Google Santa Tracker — Moving to an Android App Bundle"/><meta data-rh="true" name="twitter:site" content="@androiddev"/><meta data-rh="true" name="twitter:app:url:iphone" content="medium://p/dde180716096"/><meta data-rh="true" property="twitter:description" content="This post is the first in the series which explores the improvements made to the Google Santa Tracker Android app for 2018."/><meta data-rh="true" name="twitter:image:src" content="https://miro.medium.com/v2/resize:fit:1200/1*ksxyyNT2V-A2N626DZ9D7A.png"/><meta data-rh="true" name="twitter:card" content="summary_large_image"/><meta data-rh="true" name="twitter:creator" content="@chrisbanes"/><meta data-rh="true" name="twitter:label1" content="Reading time"/><meta data-rh="true" name="twitter:data1" content="7 min read"/><link data-rh="true" rel="icon" href="https://miro.medium.com/v2/5d8de952517e8160e40ef9841c781cdc14a5db313057fa3c3de41c6f5b494b19"/><link data-rh="true" rel="search" type="application/opensearchdescription+xml" title="Medium" href="/osd.xml"/><link data-rh="true" rel="apple-touch-icon" sizes="152x152" href="https://miro.medium.com/v2/resize:fill:304:304/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="120x120" href="https://miro.medium.com/v2/resize:fill:240:240/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="76x76" href="https://miro.medium.com/v2/resize:fill:152:152/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="60x60" href="https://miro.medium.com/v2/resize:fill:120:120/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="mask-icon" href="https://miro.medium.com/v2/resize:fill:1000:1000/7*GAOKVe--MXbEJmV9230oOQ.png" color="#171717"/><link data-rh="true" rel="preconnect" href="https://glyph.medium.com" crossOrigin=""/><link data-rh="true" id="glyph_preload_link" rel="preload" as="style" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" id="glyph_link" rel="stylesheet" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" rel="author" href="https://chrisbanes.medium.com"/><link data-rh="true" rel="canonical" href="https://medium.com/androiddevelopers/google-santa-tracker-moving-to-an-android-app-bundle-dde180716096"/><link data-rh="true" rel="alternate" href="android-app://com.medium.reader/https/medium.com/p/dde180716096"/><script data-rh="true" type="application/ld+json">{"@context":"http:\u002F\u002Fschema.org","@type":"NewsArticle","image":["https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1200\u002F1*ksxyyNT2V-A2N626DZ9D7A.png"],"url":"https:\u002F\u002Fmedium.com\u002Fandroiddevelopers\u002Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096","dateCreated":"2019-01-29T18:01:03.094Z","datePublished":"2019-01-29T18:01:03.094Z","dateModified":"2021-12-07T09:27:12.361Z","headline":"Google Santa Tracker — moving to an Android App Bundle","name":"Google Santa Tracker — moving to an Android App Bundle","description":"This post is the first in the series which explores the improvements made to the Google Santa Tracker Android app for 2018. Santa Tracker is an app which Google releases every year, allowing users to…","identifier":"dde180716096","author":{"@type":"Person","name":"Chris Banes","url":"https:\u002F\u002Fchrisbanes.medium.com"},"creator":["Chris Banes"],"publisher":{"@type":"Organization","name":"Android Developers","url":"https:\u002F\u002Fmedium.com\u002Fandroiddevelopers","logo":{"@type":"ImageObject","width":500,"height":60,"url":"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1000\u002F1*5pMw_nx55x_66tk77kutPQ.png"}},"mainEntityOfPage":"https:\u002F\u002Fmedium.com\u002Fandroiddevelopers\u002Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096"}</script><style type="text/css" data-fela-rehydration="595" data-fela-type="STATIC">html{box-sizing:border-box;-webkit-text-size-adjust:100%}*, *:before, *:after{box-sizing:inherit}body{margin:0;padding:0;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:rgba(0,0,0,0.8);position:relative;min-height:100vh}h1, h2, h3, h4, h5, h6, dl, dd, ol, ul, menu, figure, blockquote, p, pre, form{margin:0}menu, ol, ul{padding:0;list-style:none;list-style-image:none}main{display:block}a{color:inherit;text-decoration:none}a, button, input{-webkit-tap-highlight-color:transparent}img, svg{vertical-align:middle}button{background:transparent;overflow:visible}button, input, optgroup, select, textarea{margin:0}:root{--reach-tabs:1;--reach-menu-button:1}#speechify-root{font-family:Sohne, sans-serif}div[data-popper-reference-hidden="true"]{visibility:hidden;pointer-events:none}.grecaptcha-badge{visibility:hidden} /*XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>*/.hljs {background: #fff;color: black; }/* Gray DOCTYPE selectors like WebKit */ .xml .hljs-meta {color: #c0c0c0; }.hljs-comment, .hljs-quote {color: #007400; }.hljs-tag, .hljs-attribute, .hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-name {color: #aa0d91; }.hljs-variable, .hljs-template-variable {color: #3F6E74; }.hljs-code, .hljs-string, .hljs-meta .hljs-string {color: #c41a16; }.hljs-regexp, .hljs-link {color: #0E0EFF; }.hljs-title, .hljs-symbol, .hljs-bullet, .hljs-number {color: #1c00cf; }.hljs-section, .hljs-meta {color: #643820; }.hljs-title.class_, .hljs-class .hljs-title, .hljs-type, .hljs-built_in, .hljs-params {color: #5c2699; }.hljs-attr {color: #836C28; }.hljs-subst {color: #000; }.hljs-formula {background-color: #eee;font-style: italic; }.hljs-addition {background-color: #baeeba; }.hljs-deletion {background-color: #ffc8bd; }.hljs-selector-id, .hljs-selector-class {color: #9b703f; }.hljs-doctag, .hljs-strong {font-weight: bold; }.hljs-emphasis {font-style: italic; } </style><style type="text/css" data-fela-rehydration="595" data-fela-type="KEYFRAME">@-webkit-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@-moz-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE">.a{font-family:medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.b{font-weight:400}.c{background-color:rgba(255, 255, 255, 1)}.l{display:block}.m{position:sticky}.n{top:0}.o{z-index:500}.p{padding:0 24px}.q{align-items:center}.r{border-bottom:solid 1px #F2F2F2}.y{height:41px}.z{line-height:20px}.ab{display:flex}.ac{height:57px}.ae{flex:1 0 auto}.af{color:inherit}.ag{fill:inherit}.ah{font-size:inherit}.ai{border:inherit}.aj{font-family:inherit}.ak{letter-spacing:inherit}.al{font-weight:inherit}.am{padding:0}.an{margin:0}.ao{cursor:pointer}.ap:disabled{cursor:not-allowed}.aq:disabled{color:#6B6B6B}.ar:disabled{fill:#6B6B6B}.au{width:auto}.av path{fill:#242424}.aw{height:25px}.ax{margin-left:16px}.ay{border:none}.az{border-radius:20px}.ba{width:240px}.bb{background:#F9F9F9}.bc path{fill:#6B6B6B}.be{outline:none}.bf{font-family:sohne, "Helvetica Neue", Helvetica, Arial, sans-serif}.bg{font-size:14px}.bh{width:100%}.bi{padding:10px 20px 10px 0}.bj{background-color:transparent}.bk{color:#242424}.bl::placeholder{color:#6B6B6B}.bm{display:inline-block}.bn{margin-left:12px}.bo{margin-right:12px}.bp{border-radius:4px}.bq{margin-left:24px}.br{height:24px}.bx{background-color:#F9F9F9}.by{border-radius:50%}.bz{height:32px}.ca{width:32px}.cb{justify-content:center}.ch{max-width:680px}.ci{min-width:0}.cj{animation:k1 1.2s ease-in-out infinite}.ck{height:100vh}.cl{margin-bottom:16px}.cm{margin-top:48px}.cn{align-items:flex-start}.co{flex-direction:column}.cp{justify-content:space-between}.cq{margin-bottom:24px}.cw{width:80%}.cx{background-color:#F2F2F2}.dd{height:44px}.de{width:44px}.df{margin:auto 0}.dg{margin-bottom:4px}.dh{height:16px}.di{width:120px}.dj{width:80px}.dp{margin-bottom:8px}.dq{width:96%}.dr{width:98%}.ds{width:81%}.dt{margin-left:8px}.du{color:#6B6B6B}.dv{font-size:13px}.dw{height:100%}.ep{color:#FFFFFF}.eq{fill:#FFFFFF}.er{background:rgba(132, 132, 136, 1)}.es{border-color:rgba(132, 132, 136, 1)}.ew:disabled{cursor:inherit !important}.ex:disabled{opacity:0.3}.ey:disabled:hover{background:rgba(132, 132, 136, 1)}.ez:disabled:hover{border-color:rgba(132, 132, 136, 1)}.fa{border-radius:99em}.fb{border-width:1px}.fc{border-style:solid}.fd{box-sizing:border-box}.fe{text-decoration:none}.ff{text-align:center}.fi{margin-right:32px}.fj{position:relative}.fk{fill:#6B6B6B}.fn{background:transparent}.fo svg{margin-left:4px}.fp svg{fill:#6B6B6B}.fr{box-shadow:inset 0 0 0 1px rgba(0, 0, 0, 0.05)}.fs{position:absolute}.fz{margin:0 24px}.gd{background:rgba(255, 255, 255, 1)}.ge{border:1px solid #F2F2F2}.gf{box-shadow:0 1px 4px #F2F2F2}.gg{max-height:100vh}.gh{overflow-y:auto}.gi{left:0}.gj{top:calc(100vh + 100px)}.gk{bottom:calc(100vh + 100px)}.gl{width:10px}.gm{pointer-events:none}.gn{word-break:break-word}.go{word-wrap:break-word}.gp:after{display:block}.gq:after{content:""}.gr:after{clear:both}.gs{line-height:1.23}.gt{letter-spacing:0}.gu{font-style:normal}.gv{font-weight:700}.ia{align-items:baseline}.ib{width:48px}.ic{height:48px}.id{border:2px solid rgba(255, 255, 255, 1)}.ie{z-index:0}.if{box-shadow:none}.ig{border:1px solid rgba(0, 0, 0, 0.05)}.ih{margin-left:-12px}.ii{width:28px}.ij{height:28px}.ik{z-index:1}.il{width:24px}.im{margin-bottom:2px}.in{flex-wrap:nowrap}.io{font-size:16px}.ip{line-height:24px}.ir{margin:0 8px}.is{display:inline}.it{color:rgba(132, 132, 136, 1)}.iu{fill:rgba(132, 132, 136, 1)}.ix{flex:0 0 auto}.ja{flex-wrap:wrap}.jd{white-space:pre-wrap}.je{margin-right:4px}.jf{overflow:hidden}.jg{max-height:20px}.jh{text-overflow:ellipsis}.ji{display:-webkit-box}.jj{-webkit-line-clamp:1}.jk{-webkit-box-orient:vertical}.jl{word-break:break-all}.jn{padding-left:8px}.jo{padding-right:8px}.kp> *{flex-shrink:0}.kq{overflow-x:scroll}.kr::-webkit-scrollbar{display:none}.ks{scrollbar-width:none}.kt{-ms-overflow-style:none}.ku{width:74px}.kv{flex-direction:row}.kw{z-index:2}.kz{-webkit-user-select:none}.la{border:0}.lb{fill:rgba(117, 117, 117, 1)}.le{outline:0}.lf{user-select:none}.lg> svg{pointer-events:none}.lp{cursor:progress}.lq{margin-left:4px}.lr{margin-top:0px}.ls{opacity:1}.lt{padding:4px 0}.lw{width:16px}.ly{display:inline-flex}.me{max-width:100%}.mf{padding:8px 2px}.mg svg{color:#6B6B6B}.mx{clear:both}.nd{margin-left:auto}.ne{margin-right:auto}.nf{max-width:2120px}.nl{padding-top:5px}.nm{padding-bottom:5px}.no{cursor:zoom-in}.np{z-index:auto}.nr{height:auto}.ns{line-height:1.58}.nt{letter-spacing:-0.004em}.nu{font-family:source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif}.op{margin-bottom:-0.46em}.oq{font-style:italic}.or{margin-top:32px}.os{margin-bottom:14px}.ot{padding-top:24px}.ou{padding-bottom:10px}.ov{background-color:#000000}.ow{height:3px}.ox{width:3px}.oy{margin-right:20px}.oz{text-decoration:underline}.pf{box-shadow:inset 0 0 0 1px #F2F2F2}.pg{padding:0px}.ph{padding:16px 20px}.pi{flex:1 1 auto}.pk{max-height:40px}.pl{-webkit-line-clamp:2}.pm{margin-top:8px}.pn{margin-top:12px}.po{width:160px}.pp{background-image:url(https://miro.medium.com/v2/resize:fit:320/0*f1gQ1k1n3_d4-x9t.)}.pq{background-origin:border-box}.pr{background-size:cover}.ps{height:167px}.pt{background-position:50% 50%}.pu{line-height:1.12}.pv{letter-spacing:-0.022em}.pw{font-weight:600}.qr{margin-bottom:-0.28em}.qx{padding-left:30px}.qy{line-height:40px}.qz{letter-spacing:-0.009em}.ra{font-weight:300}.rb{font-size:28px}.rm{padding:2px 4px}.rn{font-size:75%}.ro> strong{font-family:inherit}.rp{font-family:source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace}.rv{margin:auto}.rw{padding-bottom:56.206088992974244%}.rx{height:0}.ry{margin-top:10px}.rz{max-width:728px}.sc{line-height:1.18}.sq{margin-bottom:-0.31em}.sr{max-width:500px}.ss{max-width:1080px}.st{padding-bottom:37.5%}.su{max-width:1826px}.sv{font-style:inherit}.sw{max-width:1796px}.sx{max-width:1258px}.sy{max-width:1024px}.sz{margin-bottom:26px}.ta{margin-top:6px}.tb{margin-right:8px}.tc{padding:8px 16px}.td{border-radius:100px}.te{transition:background 300ms ease}.tg{white-space:nowrap}.th{border-top:none}.tn{height:52px}.to{max-height:52px}.tp{box-sizing:content-box}.tq{position:static}.ts{max-width:155px}.ud{margin-bottom:48px}.ur{border-radius:2px}.ut{height:64px}.uu{width:64px}.uv{align-self:flex-end}.uz{padding-right:4px}.va{font-weight:500}.vh{margin-top:16px}.vi{color:rgba(255, 255, 255, 1)}.vj{fill:rgba(255, 255, 255, 1)}.vk{background:rgba(25, 25, 25, 1)}.vl{border-color:rgba(25, 25, 25, 1)}.vo:disabled{opacity:0.1}.vp:disabled:hover{background:rgba(25, 25, 25, 1)}.vq:disabled:hover{border-color:rgba(25, 25, 25, 1)}.vr{height:0px}.vs{border-bottom:solid 1px #E5E5E5}.vt{margin-top:56px}.vu{margin-top:72px}.vv{padding:24px 0}.vw{margin-bottom:0px}.vx{margin-right:16px}.as:hover:not(:disabled){color:rgba(25, 25, 25, 1)}.at:hover:not(:disabled){fill:rgba(25, 25, 25, 1)}.et:hover{background:rgba(113, 114, 117, 1)}.eu:hover{border-color:rgba(113, 114, 117, 1)}.ev:hover{cursor:pointer}.fl:hover{color:#242424}.fm:hover{fill:#242424}.fq:hover svg{fill:#242424}.ft:hover{background-color:rgba(0, 0, 0, 0.1)}.iq:hover{text-decoration:underline}.iv:hover:not(:disabled){color:rgba(113, 114, 117, 1)}.iw:hover:not(:disabled){fill:rgba(113, 114, 117, 1)}.ld:hover{fill:rgba(8, 8, 8, 1)}.lu:hover{fill:#000000}.lv:hover p{color:#000000}.lx:hover{color:#000000}.mh:hover svg{color:#000000}.tf:hover{background-color:#F2F2F2}.us:hover{background-color:none}.vm:hover{background:#000000}.vn:hover{border-color:#242424}.bd:focus-within path{fill:#242424}.lc:focus{fill:rgba(8, 8, 8, 1)}.mi:focus svg{color:#000000}.nq:focus{transform:scale(1.01)}.lh:active{border-style:none}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="all and (min-width: 1080px)">.d{display:none}.bw{width:64px}.cg{margin:0 64px}.cv{height:48px}.dc{margin-bottom:52px}.do{margin-bottom:48px}.ef{font-size:14px}.eg{line-height:20px}.em{font-size:13px}.eo{padding:5px 12px}.fh{display:flex}.fy{margin-bottom:68px}.gc{max-width:680px}.hq{font-size:42px}.hr{margin-top:1.19em}.hs{margin-bottom:32px}.ht{line-height:52px}.hu{letter-spacing:-0.011em}.hz{align-items:center}.kb{border-top:solid 1px #F2F2F2}.kc{border-bottom:solid 1px #F2F2F2}.kd{margin:32px 0 0}.ke{padding:3px 8px}.kn> *{margin-right:24px}.ko> :last-child{margin-right:0}.lo{margin-top:0px}.md{margin:0}.nc{max-width:1192px}.nk{margin-top:40px}.ol{font-size:20px}.om{margin-top:2.14em}.on{line-height:32px}.oo{letter-spacing:-0.003em}.pe{margin-top:32px}.qn{font-size:24px}.qo{margin-top:1.95em}.qp{line-height:30px}.qq{letter-spacing:-0.016em}.qw{margin-top:0.94em}.rg{margin-top:1.75em}.rl{margin-top:2.64em}.ru{margin-top:56px}.sn{margin-top:1.72em}.so{line-height:24px}.sp{letter-spacing:0}.tm{margin-bottom:88px}.tx{display:inline-block}.uc{padding-top:72px}.ue{flex-direction:row}.uh{margin-bottom:0}.ui{margin-right:20px}.uw{max-width:500px}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="all and (max-width: 1079.98px)">.e{display:none}.ln{margin-top:0px}.sa{margin-left:auto}.sb{text-align:center}.tw{display:inline-block}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="all and (max-width: 903.98px)">.f{display:none}.lm{margin-top:0px}.tv{display:inline-block}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="all and (max-width: 727.98px)">.g{display:none}.lk{margin-top:0px}.ll{margin-right:0px}.pj{padding:10px 12px 10px}.tu{display:inline-block}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="all and (max-width: 551.98px)">.h{display:none}.s{display:flex}.t{justify-content:space-between}.bs{width:24px}.cc{margin:0 24px}.cr{height:40px}.cy{margin-bottom:44px}.dk{margin-bottom:32px}.dx{font-size:13px}.dy{line-height:20px}.eh{padding:0px 8px 1px}.fu{margin-bottom:4px}.gw{font-size:32px}.gx{margin-top:1.01em}.gy{margin-bottom:24px}.gz{line-height:38px}.ha{letter-spacing:-0.014em}.hv{align-items:flex-start}.iy{flex-direction:column}.jb{margin-bottom:2px}.jp{margin:24px -24px 0}.jq{padding:0}.kf> *{margin-right:8px}.kg> :last-child{margin-right:24px}.kx{margin-left:0px}.li{margin-top:0px}.lj{margin-right:0px}.lz{margin:0}.mj{border:1px solid #F2F2F2}.mk{border-radius:99em}.ml{padding:0px 16px 0px 12px}.mm{height:38px}.mn{align-items:center}.mp svg{margin-right:8px}.my{max-width:100%}.ng{margin-top:32px}.nv{font-size:18px}.nw{margin-top:1.56em}.nx{line-height:28px}.ny{letter-spacing:-0.003em}.pa{margin-top:24px}.px{font-size:20px}.py{margin-top:1.2em}.pz{line-height:24px}.qa{letter-spacing:0}.qs{margin-top:0.67em}.rc{margin-top:1.08em}.rh{margin-top:2em}.rq{margin-top:40px}.sd{font-size:16px}.se{margin-top:1.23em}.ti{margin-bottom:80px}.tt{display:inline-block}.ty{padding-top:48px}.up{margin-bottom:20px}.uq{margin-right:0}.vb{font-size:24px}.vc{line-height:30px}.vd{letter-spacing:-0.016em}.mo:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="all and (min-width: 904px) and (max-width: 1079.98px)">.i{display:none}.bv{width:64px}.cf{margin:0 64px}.cu{height:48px}.db{margin-bottom:52px}.dn{margin-bottom:48px}.ed{font-size:14px}.ee{line-height:20px}.ek{font-size:13px}.el{padding:5px 12px}.fg{display:flex}.fx{margin-bottom:68px}.gb{max-width:680px}.hl{font-size:42px}.hm{margin-top:1.19em}.hn{margin-bottom:32px}.ho{line-height:52px}.hp{letter-spacing:-0.011em}.hy{align-items:center}.jx{border-top:solid 1px #F2F2F2}.jy{border-bottom:solid 1px #F2F2F2}.jz{margin:32px 0 0}.ka{padding:3px 8px}.kl> *{margin-right:24px}.km> :last-child{margin-right:0}.mc{margin:0}.nb{max-width:1192px}.nj{margin-top:40px}.oh{font-size:20px}.oi{margin-top:2.14em}.oj{line-height:32px}.ok{letter-spacing:-0.003em}.pd{margin-top:32px}.qj{font-size:24px}.qk{margin-top:1.95em}.ql{line-height:30px}.qm{letter-spacing:-0.016em}.qv{margin-top:0.94em}.rf{margin-top:1.75em}.rk{margin-top:2.64em}.rt{margin-top:56px}.sk{margin-top:1.72em}.sl{line-height:24px}.sm{letter-spacing:0}.tl{margin-bottom:88px}.ub{padding-top:72px}.uf{flex-direction:row}.uj{margin-bottom:0}.uk{margin-right:20px}.ux{max-width:500px}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="all and (min-width: 728px) and (max-width: 903.98px)">.j{display:none}.w{display:flex}.x{justify-content:space-between}.bu{width:64px}.ce{margin:0 48px}.ct{height:48px}.da{margin-bottom:52px}.dm{margin-bottom:48px}.eb{font-size:13px}.ec{line-height:20px}.ej{padding:0px 8px 1px}.fw{margin-bottom:68px}.ga{max-width:680px}.hg{font-size:42px}.hh{margin-top:1.19em}.hi{margin-bottom:32px}.hj{line-height:52px}.hk{letter-spacing:-0.011em}.hx{align-items:center}.jt{border-top:solid 1px #F2F2F2}.ju{border-bottom:solid 1px #F2F2F2}.jv{margin:32px 0 0}.jw{padding:3px 8px}.kj> *{margin-right:24px}.kk> :last-child{margin-right:0}.mb{margin:0}.na{max-width:100%}.ni{margin-top:40px}.od{font-size:20px}.oe{margin-top:2.14em}.of{line-height:32px}.og{letter-spacing:-0.003em}.pc{margin-top:32px}.qf{font-size:24px}.qg{margin-top:1.95em}.qh{line-height:30px}.qi{letter-spacing:-0.016em}.qu{margin-top:0.94em}.re{margin-top:1.75em}.rj{margin-top:2.64em}.rs{margin-top:56px}.sh{margin-top:1.72em}.si{line-height:24px}.sj{letter-spacing:0}.tk{margin-bottom:88px}.ua{padding-top:72px}.ug{flex-direction:row}.ul{margin-bottom:0}.um{margin-right:20px}.uy{max-width:500px}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="all and (min-width: 552px) and (max-width: 727.98px)">.k{display:none}.u{display:flex}.v{justify-content:space-between}.bt{width:24px}.cd{margin:0 24px}.cs{height:40px}.cz{margin-bottom:44px}.dl{margin-bottom:32px}.dz{font-size:13px}.ea{line-height:20px}.ei{padding:0px 8px 1px}.fv{margin-bottom:4px}.hb{font-size:32px}.hc{margin-top:1.01em}.hd{margin-bottom:24px}.he{line-height:38px}.hf{letter-spacing:-0.014em}.hw{align-items:flex-start}.iz{flex-direction:column}.jc{margin-bottom:2px}.jr{margin:24px 0 0}.js{padding:0}.kh> *{margin-right:8px}.ki> :last-child{margin-right:8px}.ky{margin-left:0px}.ma{margin:0}.mq{border:1px solid #F2F2F2}.mr{border-radius:99em}.ms{padding:0px 16px 0px 12px}.mt{height:38px}.mu{align-items:center}.mw svg{margin-right:8px}.mz{max-width:100%}.nh{margin-top:32px}.nz{font-size:18px}.oa{margin-top:1.56em}.ob{line-height:28px}.oc{letter-spacing:-0.003em}.pb{margin-top:24px}.qb{font-size:20px}.qc{margin-top:1.2em}.qd{line-height:24px}.qe{letter-spacing:0}.qt{margin-top:0.67em}.rd{margin-top:1.08em}.ri{margin-top:2em}.rr{margin-top:40px}.sf{font-size:16px}.sg{margin-top:1.23em}.tj{margin-bottom:80px}.tz{padding-top:48px}.un{margin-bottom:20px}.uo{margin-right:0}.ve{font-size:24px}.vf{line-height:30px}.vg{letter-spacing:-0.016em}.mv:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="print">.tr{display:none}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="(orientation: landscape) and (max-width: 903.98px)">.jm{max-height:none}</style><style type="text/css" data-fela-rehydration="595" data-fela-type="RULE" media="(prefers-reduced-motion: no-preference)">.nn{transition:transform 300ms cubic-bezier(0.2, 0, 0.2, 1)}</style></head><body><div id="root"><div class="a b c"><div class="d e f g h i j k"></div><script>document.domain = document.domain;</script><div class="l c"><div class="l m n o c"><div class="p q r s t u v w x i d y z"><a class="du ag dv bf ak b am an ao ap aq ar as at s u w i d q dw z" href="https://rsci.app.link/?%24canonical_url=https%3A%2F%2Fmedium.com%2Fp%2Fdde180716096&amp;%7Efeature=LoOpenInAppButton&amp;%7Echannel=ShowPostUnderCollection&amp;source=---top_nav_layout_nav----------------------------------" rel="noopener follow">Open in app<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="none" viewBox="0 0 10 10" class="dt"><path fill="currentColor" d="M.985 8.485a.375.375 0 1 0 .53.53zM8.75 1.25h.375A.375.375 0 0 0 8.75.875zM8.375 6.5a.375.375 0 1 0 .75 0zM3.5.875a.375.375 0 1 0 0 .75zm-1.985 8.14 7.5-7.5-.53-.53-7.5 7.5zm6.86-7.765V6.5h.75V1.25zM3.5 1.625h5.25v-.75H3.5z"></path></svg></a><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><button class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton">Sign up</button></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&amp;redirect=https%3A%2F%2Fmedium.com%2Fandroiddevelopers%2Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096&amp;source=post_page---top_nav_layout_nav-----------------------global_nav-----------">Sign in</a></span></p></div></div></div><div class="p q r ab ac"><div class="ab q ae"><a class="af ag ah ai aj ak al am an ao ap aq ar as at ab" aria-label="Homepage" data-testid="headerMediumLogo" rel="noopener follow" href="/?source=---top_nav_layout_nav----------------------------------"><svg xmlns="http://www.w3.org/2000/svg" width="719" height="160" fill="none" viewBox="0 0 719 160" class="au av aw"><path fill="#242424" d="m174.104 9.734.215-.047V8.02H130.39L89.6 103.89 48.81 8.021H1.472v1.666l.212.047c8.018 1.81 12.09 4.509 12.09 14.242V137.93c0 9.734-4.087 12.433-12.106 14.243l-.212.047v1.671h32.118v-1.665l-.213-.048c-8.018-1.809-12.089-4.509-12.089-14.242V30.586l52.399 123.305h2.972l53.925-126.743V140.75c-.687 7.688-4.721 10.062-11.982 11.701l-.215.05v1.652h55.948v-1.652l-.215-.05c-7.269-1.639-11.4-4.013-12.087-11.701l-.037-116.774h.037c0-9.733 4.071-12.432 12.087-14.242m25.555 75.488c.915-20.474 8.268-35.252 20.606-35.507 3.806.063 6.998 1.312 9.479 3.714 5.272 5.118 7.751 15.812 7.368 31.793zm-.553 5.77h65.573v-.275c-.186-15.656-4.721-27.834-13.466-36.196-7.559-7.227-18.751-11.203-30.507-11.203h-.263c-6.101 0-13.584 1.48-18.909 4.16-6.061 2.807-11.407 7.003-15.855 12.511-7.161 8.874-11.499 20.866-12.554 34.343q-.05.606-.092 1.212a50 50 0 0 0-.065 1.151 85.807 85.807 0 0 0-.094 5.689c.71 30.524 17.198 54.917 46.483 54.917 25.705 0 40.675-18.791 44.407-44.013l-1.886-.664c-6.557 13.556-18.334 21.771-31.738 20.769-18.297-1.369-32.314-19.922-31.042-42.395m139.722 41.359c-2.151 5.101-6.639 7.908-12.653 7.908s-11.513-4.129-15.418-11.63c-4.197-8.053-6.405-19.436-6.405-32.92 0-28.067 8.729-46.22 22.24-46.22 5.657 0 10.111 2.807 12.236 7.704zm43.499 20.008c-8.019-1.897-12.089-4.722-12.089-14.951V1.309l-48.716 14.353v1.757l.299-.024c6.72-.543 11.278.386 13.925 2.83 2.072 1.915 3.082 4.853 3.082 8.987v18.66c-4.803-3.067-10.516-4.56-17.448-4.56-14.059 0-26.909 5.92-36.176 16.672-9.66 11.205-14.767 26.518-14.767 44.278-.003 31.72 15.612 53.039 38.851 53.039 13.595 0 24.533-7.449 29.54-20.013v16.865h43.711v-1.746zM424.1 19.819c0-9.904-7.468-17.374-17.375-17.374-9.859 0-17.573 7.632-17.573 17.374s7.721 17.374 17.573 17.374c9.907 0 17.375-7.47 17.375-17.374m11.499 132.546c-8.019-1.897-12.089-4.722-12.089-14.951h-.035V43.635l-43.714 12.551v1.705l.263.024c9.458.842 12.047 4.1 12.047 15.152v81.086h43.751v-1.746zm112.013 0c-8.018-1.897-12.089-4.722-12.089-14.951V43.635l-41.621 12.137v1.71l.246.026c7.733.813 9.967 4.257 9.967 15.36v59.279c-2.578 5.102-7.415 8.131-13.274 8.336-9.503 0-14.736-6.419-14.736-18.073V43.638l-43.714 12.55v1.703l.262.024c9.459.84 12.05 4.097 12.05 15.152v50.17a56.3 56.3 0 0 0 .91 10.444l.787 3.423c3.701 13.262 13.398 20.197 28.59 20.197 12.868 0 24.147-7.966 29.115-20.43v17.311h43.714v-1.747zm169.818 1.788v-1.749l-.213-.05c-8.7-2.006-12.089-5.789-12.089-13.49v-63.79c0-19.89-11.171-31.761-29.883-31.761-13.64 0-25.141 7.882-29.569 20.16-3.517-13.01-13.639-20.16-28.606-20.16-13.146 0-23.449 6.938-27.869 18.657V43.643L545.487 55.68v1.715l.263.024c9.345.829 12.047 4.181 12.047 14.95v81.784h40.787v-1.746l-.215-.053c-6.941-1.631-9.181-4.606-9.181-12.239V66.998c1.836-4.289 5.537-9.37 12.853-9.37 9.086 0 13.692 6.296 13.692 18.697v77.828h40.797v-1.746l-.215-.053c-6.94-1.631-9.18-4.606-9.18-12.239V75.066a42 42 0 0 0-.578-7.26c1.947-4.661 5.86-10.177 13.475-10.177 9.214 0 13.691 6.114 13.691 18.696v77.828z"></path></svg></a><div class="ax h"><div class="ab ay az ba bb q bc bd"><div class="bm" aria-hidden="false" aria-describedby="searchResults" aria-labelledby="searchResults"></div><div class="bn bo ab"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div><input role="combobox" aria-controls="searchResults" aria-expanded="false" aria-label="search" data-testid="headerSearchInput" tabindex="0" class="ay be bf bg z bh bi bj bk bl" placeholder="Search" value=""/></div></div></div><div class="h k w fg fh"><div class="fi ab"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerWriteButton" rel="noopener follow" href="/m/signin?operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fnew-story&amp;source=---top_nav_layout_nav-----------------------new_post_topnav-----------"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Write"><path fill="currentColor" d="M14 4a.5.5 0 0 0 0-1zm7 6a.5.5 0 0 0-1 0zm-7-7H4v1h10zM3 4v16h1V4zm1 17h16v-1H4zm17-1V10h-1v10zm-1 1a1 1 0 0 0 1-1h-1zM3 20a1 1 0 0 0 1 1v-1zM4 3a1 1 0 0 0-1 1h1z"></path><path stroke="currentColor" d="m17.5 4.5-8.458 8.458a.25.25 0 0 0-.06.098l-.824 2.47a.25.25 0 0 0 .316.316l2.47-.823a.25.25 0 0 0 .098-.06L19.5 6.5m-2-2 2.323-2.323a.25.25 0 0 1 .354 0l1.646 1.646a.25.25 0 0 1 0 .354L19.5 6.5m-2-2 2 2"></path></svg><div class="dt l">Write</div></div></a></span></div></div><div class="k j i d"><div class="fi ab"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSearchButton" rel="noopener follow" href="/search?source=---top_nav_layout_nav----------------------------------"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Search"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div></a></div></div><div class="fi h k j"><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><button class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton">Sign up</button></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&amp;redirect=https%3A%2F%2Fmedium.com%2Fandroiddevelopers%2Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096&amp;source=post_page---top_nav_layout_nav-----------------------global_nav-----------">Sign in</a></span></p></div></div></div><div class="l" aria-hidden="false"><button class="ay fn am ab q ao fo fp fq" aria-label="user options menu" data-testid="headerUserIcon"><div class="l fj"><img alt="" class="l fd by bz ca cx" src="https://miro.medium.com/v2/resize:fill:64:64/1*dmbNkD5D-u45r44go_cf0g.png" width="32" height="32" loading="lazy" role="presentation"/><div class="fr by l bz ca fs n ay ft"></div></div></button></div></div></div><div class="l"><div class="fu fv fw fx fy l"><div class="ab cb"><div class="ci bh fz ga gb gc"></div></div><article><div class="l"><div class="l"><span class="l"></span><section><div><div class="fs gi gj gk gl gm"></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><div><h1 id="d6d2" class="pw-post-title gs gt gu bf gv gw gx gy gz ha hb hc hd he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu bk" data-testid="storyTitle">Google Santa Tracker — moving to an Android App Bundle</h1><div><div class="speechify-ignore ab cp"><div class="speechify-ignore bh l"><div class="hv hw hx hy hz ab"><div><div class="ab ia"><div><div class="bm" aria-hidden="false"><a rel="noopener follow" href="/@chrisbanes?source=post_page---byline--dde180716096--------------------------------"><div class="l ib ic by id ie"><div class="l fj"><img alt="Chris Banes" class="l fd by dd de cx" src="https://miro.medium.com/v2/resize:fill:88:88/1*ik17e6aHCcc160bYFl-Evg.jpeg" width="44" height="44" loading="lazy" data-testid="authorPhoto"/><div class="if by l dd de fs n ig ft"></div></div></div></a></div></div><div class="ih ab fj"><div><div class="bm" aria-hidden="false"><a href="https://medium.com/androiddevelopers?source=post_page---byline--dde180716096--------------------------------" rel="noopener follow"><div class="l ii ij by id ik"><div class="l fj"><img alt="Android Developers" class="l fd by br il cx" src="https://miro.medium.com/v2/resize:fill:48:48/1*4Tg6pPzer7cIarYaszIKaQ.png" width="24" height="24" loading="lazy" data-testid="publicationPhoto"/><div class="if by l br il fs n ig ft"></div></div></div></a></div></div></div></div></div><div class="bn bh l"><div class="ab"><div style="flex:1"><span class="bf b bg z bk"><div class="im ab q"><div class="ab q in"><div class="ab q"><div><div class="bm" aria-hidden="false"><p class="bf b io ip bk"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" data-testid="authorName" rel="noopener follow" href="/@chrisbanes?source=post_page---byline--dde180716096--------------------------------">Chris Banes</a></p></div></div></div><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span><p class="bf b io ip du"><span><a class="it iu ah ai aj ak al am an ao ap aq ar ex iv iw" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F9303277cb6db&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fandroiddevelopers%2Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096&amp;user=Chris+Banes&amp;userId=9303277cb6db&amp;source=post_page-9303277cb6db--byline--dde180716096---------------------post_header-----------">Follow</a></span></p></div></div></span></div></div><div class="l ix"><span class="bf b bg z du"><div class="ab cn iy iz ja"><div class="jb jc ab"><div class="bf b bg z du ab jd"><span class="je l ix">Published in</span><div><div class="l" aria-hidden="false"><a class="af ag ah ai aj ak al am an ao ap aq ar iq ab q" data-testid="publicationName" href="https://medium.com/androiddevelopers?source=post_page---byline--dde180716096--------------------------------" rel="noopener follow"><p class="bf b bg z jf jg jh ji jj jk jl jm bk">Android Developers</p></a></div></div></div><div class="h k"><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span></div></div><span class="bf b bg z du"><div class="ab ae"><span data-testid="storyReadTime">7 min read</span><div class="jn jo l" aria-hidden="true"><span class="l" aria-hidden="true"><span class="bf b bg z du">·</span></span></div><span data-testid="storyPublishDate">Jan 29, 2019</span></div></span></div></span></div></div></div><div class="ab cp jp jq jr js jt ju jv jw jx jy jz ka kb kc kd ke"><div class="h k w fg fh q"><div class="ku l"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fandroiddevelopers%2Fdde180716096&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fandroiddevelopers%2Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096&amp;user=Chris+Banes&amp;userId=9303277cb6db&amp;source=---header_actions--dde180716096---------------------clap_footer-----------"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></div><div><div class="bm" aria-hidden="false"><button class="ao la ls lt ab q fk lu lv" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lr"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg><p class="bf b dv z du"><span class="pw-responses-count lq lr">1</span></p></button></div></div></div><div class="ab q kf kg kh ki kj kk kl km kn ko kp kq kr ks kt"><div class="lw k j i d"></div><div class="h k"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2Fdde180716096&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fandroiddevelopers%2Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096&amp;source=---header_actions--dde180716096---------------------bookmark_footer-----------"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lx" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="fd ly cn"><div class="l ae"><div class="ab cb"><div class="lz ma mb mc md me ci bh"><div class="ab"><div class="bm bh" aria-hidden="false"><div><div class="bm" aria-hidden="false"><button aria-label="Listen" data-testid="audioPlayButton" class="af fk ah ai aj ak al mf an ao ap ex mg mh lv mi mj mk ml mm s mn mo mp mq mr ms mt u mu mv mw"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M3 12a9 9 0 1 1 18 0 9 9 0 0 1-18 0m9-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2m3.376 10.416-4.599 3.066a.5.5 0 0 1-.777-.416V8.934a.5.5 0 0 1 .777-.416l4.599 3.066a.5.5 0 0 1 0 .832" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Listen</p></div></button></div></div></div></div></div></div></div></div><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="headerSocialShareButton" class="af fk ah ai aj ak al mf an ao ap ex mg mh lv mi mj mk ml mm s mn mo mp mq mr ms mt u mu mv mw"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Share</p></div></button></div></div></div></div></div></div></div></div></div></div></div><div class="mx"><div class="ab cb"><div class="lz my ma mz mb na cf nb cg nc ci bh"><figure class="ng nh ni nj nk mx nl nm paragraph-image"><div role="button" tabindex="0" class="nn no fj np bh nq"><div class="nd ne nf"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*ksxyyNT2V-A2N626DZ9D7A.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*ksxyyNT2V-A2N626DZ9D7A.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*ksxyyNT2V-A2N626DZ9D7A.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*ksxyyNT2V-A2N626DZ9D7A.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*ksxyyNT2V-A2N626DZ9D7A.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*ksxyyNT2V-A2N626DZ9D7A.png 1100w, https://miro.medium.com/v2/resize:fit:2000/format:webp/1*ksxyyNT2V-A2N626DZ9D7A.png 2000w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 1000px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*ksxyyNT2V-A2N626DZ9D7A.png 640w, https://miro.medium.com/v2/resize:fit:720/1*ksxyyNT2V-A2N626DZ9D7A.png 720w, https://miro.medium.com/v2/resize:fit:750/1*ksxyyNT2V-A2N626DZ9D7A.png 750w, https://miro.medium.com/v2/resize:fit:786/1*ksxyyNT2V-A2N626DZ9D7A.png 786w, https://miro.medium.com/v2/resize:fit:828/1*ksxyyNT2V-A2N626DZ9D7A.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*ksxyyNT2V-A2N626DZ9D7A.png 1100w, https://miro.medium.com/v2/resize:fit:2000/1*ksxyyNT2V-A2N626DZ9D7A.png 2000w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 1000px"/><img alt="" class="bh me nr c" width="1000" height="419" loading="eager" role="presentation"/></picture></div></div></figure></div></div></div><div class="ab cb"><div class="ci bh fz ga gb gc"><p id="4b52" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk"><em class="oq">This post is the first in the series which explores the improvements made to the Google Santa Tracker Android app for 2018.</em></p></div></div></div><div class="ab cb or os ot ou" role="separator"><span class="ov by bm ow ox oy"></span><span class="ov by bm ow ox oy"></span><span class="ov by bm ow ox"></span></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><p id="c498" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">Santa Tracker is an app which Google releases every year, allowing users to track Santa as he makes his way around the globe. Unfortunately Santa Tracker has drastically grown in size over the years, resulting in a hefty <strong class="nu gv">60MB</strong> download size in 2017. Our goal for the recent holiday season was to drastically reduce that, and this post talks through how we did that.</p><p id="665e" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">If you’ve used the <a class="af oz" href="https://play.google.com/store/apps/details?id=com.google.android.apps.santatracker" rel="noopener ugc nofollow" target="_blank">Google Santa Tracker Android app</a> you’ll know that it has two main features, the “Tracker” which allows users to track Santa as he makes his journey across the globe, and a collection of mini-games which are available to play throughout December, designed to help users to get into the holiday spirit 🎄.</p><p id="dade" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">The “Tracker” is the primary feature of the app and is where most of our usage comes from. The feature is actually only available for the 26 hours* before Christmas (December 24th), and during that time the tracker is the most used feature. To give you an idea of numbers, <strong class="nu gv">37%</strong> of all screen views (during December) happened on the 24th December, and over <strong class="nu gv">65%</strong> of screen views on that day were on the tracker.</p><p id="a0ff" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">So why is this important? Knowing what our primary feature was allowed us to think about what parts of the app were critical in the initial install, and which parts were secondary and could potentially be split out into separate modules which could be dynamically installed, making our initial install smaller. The 2017 app was released as a single APK which contained everything, including all of the games, even if the user did not play them.</p><p id="2b18" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">We knew it was time for Santa Tracker to go on a diet, so we set a goal of shrinking our initial download size down to <em class="oq">just</em> 10MB 😥.</p><p id="05ad" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">Why that size you ask? Well it is shown to have a 30% higher conversion rate than a 100MB sized app. Santa Tracker is not an app where we track conversion rate but a lot of apps do. 10MB was also a very low goal to try and achieve, to see if it was even possible. For more info on the stats behind this, read this article from the <a class="af oz" href="https://medium.com/googleplaydev" rel="noopener">Google Play team</a>:</p><div class="pa pb pc pd pe pf"><a rel="noopener follow" target="_blank" href="/googleplaydev/shrinking-apks-growing-installs-5d3fcba23ce2?source=post_page-----dde180716096--------------------------------"><div class="pg ab ix"><div class="ph ab co cb pi pj"><h2 class="bf gv io z jf pk jh ji pl jk jm gt bk">Shrinking APKs, growing installs</h2><div class="pm l"><h3 class="bf b io z jf pk jh ji pl jk jm du">How your app’s APK size impacts install conversion rates</h3></div><div class="pn l"><p class="bf b dv z jf pk jh ji pl jk jm du">medium.com</p></div></div><div class="po l"><div class="pp l pq pr ps po pt me pf"></div></div></div></a></div><h1 id="b701" class="pu pv gu bf pw px py pz qa qb qc qd qe qf qg qh qi qj qk ql qm qn qo qp qq qr bk">Dynamic Delivery</h1><p id="5f74" class="pw-post-body-paragraph ns nt gu nu b nv qs nx ny nz qt ob oc od qu of og oh qv oj ok ol qw on oo op gn bk">You may have heard about the new<a class="af oz" href="https://developer.android.com/platform/technology/app-bundle/" rel="noopener ugc nofollow" target="_blank"> Android App Bundle</a> format, which allows the Google Play store to dynamically deliver a customized app with only the parts relevant to the device. This was an easy first step for us. By simply uploading an AAB (Android App Bundle) instead of an APK, we instantly managed to reduce the download size by nearly <strong class="nu gv">20%</strong> to <strong class="nu gv">48.5MB</strong> (from 60MB). That’s a <em class="oq">huge</em> saving for the <em class="oq">tiny</em> amount of work we had to do!</p><blockquote class="qx"><p id="47c5" class="qy qz gu bf ra rb rc rd re rf rg op du">If<!-- --> you only take away one thing from reading this post, make sure it is to try uploading an AAB instead of an APK for your app. The chances are high that this small change will save your users time and money.</p></blockquote><p id="d6f5" class="pw-post-body-paragraph ns nt gu nu b nv rh nx ny nz ri ob oc od rj of og oh rk oj ok ol rl on oo op gn bk">So how does Google Play achieve that saving? By being able to deliver something optimized for a single device, the infrastructure can remove all of the language resources, density resources, and native libraries which are not applicable for the device. Example, if your device set to <code class="cx rm rn ro rp b">fr-FR</code>, has a <code class="cx rm rn ro rp b">xxhdpi</code> display, with an <code class="cx rm rn ro rp b">arm64-v8a</code> CPU, the APK delivered will only include the necessary resources, and not for example, any strings localized to Spanish. You’d be surprised at how much space things like localized strings can take up.</p><p id="abe3" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">Make sure to watch the ‘<a class="af oz" href="https://www.youtube.com/watch?v=QdoEcfibG-s" rel="noopener ugc nofollow" target="_blank">Optimize Your App Size</a>’ talk from <a class="af oz" href="https://developer.android.com/dev-summit/" rel="noopener ugc nofollow" target="_blank">Android Dev Summit ’18</a> for more info:</p><figure class="rq rr rs rt ru mx"><div class="rv jf l fj"><div class="rw rx l"></div></div><figcaption class="ry ff rz nd ne sa sb bf b bg z du">‘Optimize Your App Size’ talk from ADS ‘18</figcaption></figure><h1 id="7d36" class="pu pv gu bf pw px py pz qa qb qc qd qe qf qg qh qi qj qk ql qm qn qo qp qq qr bk">Feature modules</h1><p id="2668" class="pw-post-body-paragraph ns nt gu nu b nv qs nx ny nz qt ob oc od qu of og oh qv oj ok ol qw on oo op gn bk">While we made a good start, we were quite far away from our goal of 10MB! So we started thinking about which features of the app could be split out as dynamic feature modules, where they could be fetched on demand using the<a class="af oz" href="https://developer.android.com/guide/app-bundle/playcore" rel="noopener ugc nofollow" target="_blank"> Play Core library</a>. Luckily our app was already logically split out into nice separate chunks: the games 🎮.</p><p id="b117" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">A plan formed to convert each game into a separate feature module, and install them only when the user first chose to play that particular game. Sounds great, right? Well while logically the games were all separate, the code base was… <em class="oq">not</em>. It had grown over several years into a tangled heap of interdependent modules, layers of libraries modules underneath everything, and duplicate resources everywhere.</p><p id="b727" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">Our first job was to fix the tight coupling and assert some clean separation between the game modules. We painstakingly untangled all of the game modules so that each was a completely separate module, using the new <code class="cx rm rn ro rp b">com.android.dynamic-feature</code> Gradle plugin. For any games which had shared dependencies (e.g, the ‘Penguin Swim’ and ‘Elf Jetpack’ games share a lot of code), the dependencies were added into the ‘base’ module so that they would be only installed once.</p><h2 id="9ae3" class="sc pv gu bf pw sd se dy qa sf sg ea qe od sh si sj oh sk sl sm ol sn so sp sq bk">Implementing feature modules</h2><p id="7ce5" class="pw-post-body-paragraph ns nt gu nu b nv qs nx ny nz qt ob oc od qu of og oh qv oj ok ol qw on oo op gn bk">As discussed above, the majority of the work in moving to feature modules is actually organizing existing code, but there is still some integration which needs to be done with the <a class="af oz" href="https://developer.android.com/guide/app-bundle/playcore" rel="noopener ugc nofollow" target="_blank">Play Core library</a> to hook it all up.</p><p id="33a2" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">First let’s talk about the UX when a user launches a game. We start a ‘splash screen’ activity, which displays the logo and title of the game, and then after a brief period it launches the game. All of the information about the game to launch is passed to the splash activity as intent extras. This behavior has been the same in the app for a number of years and wasn’t something that we wanted to change. It did however provide a very nice integration point for fetching dynamic feature modules.</p><p id="85a1" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">For 2018 we updated the splash behavior so that we send four key pieces of information, the title of the game, game icon, Activity class to launch, and the ID of the feature module it is in. Once the splash activity is shown, it checks whether the relevant feature module is installed. If it is, it just launches the game as normal. If not, it requests an install via the Play Core library, displaying a progress bar indicating the ongoing download:</p><figure class="rq rr rs rt ru mx nd ne paragraph-image"><div class="nd ne sr"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1000/format:webp/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 1000w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 500px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 1100w, https://miro.medium.com/v2/resize:fit:1000/1*KPoBN-zNlJPVmjrIy8A8jQ.gif 1000w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 500px"/><img alt="" class="bh me nr c" width="500" height="625" loading="lazy" role="presentation"/></picture></div></figure><p id="1f1b" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">We found out early on in testing that you need to be careful about the conditions in which you install a feature module. We did not want to inadvertently cost the user money by installing feature modules while they were on their mobile network. To combat that we added a confirmation dialog when we detected that the device was connected to a metered network (such as a mobile network):</p><figure class="rq rr rs rt ru mx nd ne paragraph-image"><div role="button" tabindex="0" class="nn no fj np bh nq"><div class="nd ne ss"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*2qCP_mHG0gr4eKJ0Md0H1A.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*2qCP_mHG0gr4eKJ0Md0H1A.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*2qCP_mHG0gr4eKJ0Md0H1A.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*2qCP_mHG0gr4eKJ0Md0H1A.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*2qCP_mHG0gr4eKJ0Md0H1A.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*2qCP_mHG0gr4eKJ0Md0H1A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*2qCP_mHG0gr4eKJ0Md0H1A.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*2qCP_mHG0gr4eKJ0Md0H1A.png 640w, https://miro.medium.com/v2/resize:fit:720/1*2qCP_mHG0gr4eKJ0Md0H1A.png 720w, https://miro.medium.com/v2/resize:fit:750/1*2qCP_mHG0gr4eKJ0Md0H1A.png 750w, https://miro.medium.com/v2/resize:fit:786/1*2qCP_mHG0gr4eKJ0Md0H1A.png 786w, https://miro.medium.com/v2/resize:fit:828/1*2qCP_mHG0gr4eKJ0Md0H1A.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*2qCP_mHG0gr4eKJ0Md0H1A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*2qCP_mHG0gr4eKJ0Md0H1A.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh me nr c" width="700" height="743" loading="lazy" role="presentation"/></picture></div></div><figcaption class="ry ff rz nd ne sa sb bf b bg z du">Confirmation dialog shown when the device is connected to a metered network</figcaption></figure><p id="1fb6" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">The overall logic for this looks like this:</p><figure class="rq rr rs rt ru mx"><div class="rv jf l fj"><div class="st rx l"></div></div></figure><p id="9156" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">The <code class="cx rm rn ro rp b">startModuleInstall()</code> method is a little more complex due to how the Play Core API works. You need to attach a listener which will be invoked during an install, and then request an install, like so:</p><figure class="rq rr rs rt ru mx"><div class="rv jf l fj"><div class="st rx l"></div></div></figure><p id="b699" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">The listener will later receive an install complete signal, and finally we launch the game. You can find the complete code <a class="af oz" href="https://github.com/google/santa-tracker-android/tree/master/santa-tracker/src/main/java/com/google/android/apps/santatracker/games/SplashActivity.kt" rel="noopener ugc nofollow" target="_blank">here</a>.</p><h1 id="41ca" class="pu pv gu bf pw px py pz qa qb qc qd qe qf qg qh qi qj qk ql qm qn qo qp qq qr bk">Results</h1><p id="d4a4" class="pw-post-body-paragraph ns nt gu nu b nv qs nx ny nz qt ob oc od qu of og oh qv oj ok ol qw on oo op gn bk">If you’ve got this far into the post you probably want to see how we did…</p><p id="7ef8" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">Android Studio has a great way to analyze your App Bundles (and APKs), to drill down and see a download size value for each feature module. Using that we can see that our initial download size is 11.6MB (missing out on our 10MB goal), and our total download size is 25.5MB.</p><figure class="rq rr rs rt ru mx nd ne paragraph-image"><div role="button" tabindex="0" class="nn no fj np bh nq"><div class="nd ne su"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*z6BiUOLlfqpwx58ywfSsVw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*z6BiUOLlfqpwx58ywfSsVw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*z6BiUOLlfqpwx58ywfSsVw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*z6BiUOLlfqpwx58ywfSsVw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*z6BiUOLlfqpwx58ywfSsVw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*z6BiUOLlfqpwx58ywfSsVw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*z6BiUOLlfqpwx58ywfSsVw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*z6BiUOLlfqpwx58ywfSsVw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*z6BiUOLlfqpwx58ywfSsVw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*z6BiUOLlfqpwx58ywfSsVw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*z6BiUOLlfqpwx58ywfSsVw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*z6BiUOLlfqpwx58ywfSsVw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*z6BiUOLlfqpwx58ywfSsVw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*z6BiUOLlfqpwx58ywfSsVw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh me nr c" width="700" height="386" loading="lazy" role="presentation"/></picture></div></div><figcaption class="ry ff rz nd ne sa sb bf b bg z du"><em class="sv">* Download size calculated using Analyze Bundle feature in Android Studio</em></figcaption></figure><figure class="rq rr rs rt ru mx nd ne paragraph-image"><div role="button" tabindex="0" class="nn no fj np bh nq"><div class="nd ne sw"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*aamb-oJ9fhE-7VPpvHh-bA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*aamb-oJ9fhE-7VPpvHh-bA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*aamb-oJ9fhE-7VPpvHh-bA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*aamb-oJ9fhE-7VPpvHh-bA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*aamb-oJ9fhE-7VPpvHh-bA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*aamb-oJ9fhE-7VPpvHh-bA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*aamb-oJ9fhE-7VPpvHh-bA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*aamb-oJ9fhE-7VPpvHh-bA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*aamb-oJ9fhE-7VPpvHh-bA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*aamb-oJ9fhE-7VPpvHh-bA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*aamb-oJ9fhE-7VPpvHh-bA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*aamb-oJ9fhE-7VPpvHh-bA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*aamb-oJ9fhE-7VPpvHh-bA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*aamb-oJ9fhE-7VPpvHh-bA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh me nr c" width="700" height="392" loading="lazy" role="presentation"/></picture></div></div><figcaption class="ry ff rz nd ne sa sb bf b bg z du">Chart showing how the module sizes compare</figcaption></figure><p id="134a" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">But…. these values are only looking at the generated Android App Bundle archive, and do not take into account any savings which Google Play can provide through Dynamic Delivery (which we discussed above). The most sure way to see the download size for a particular device is by looking on the <a class="af oz" href="https://play.google.com/apps/publish/" rel="noopener ugc nofollow" target="_blank">Google Play Developer Console</a>. After uploading an App Bundle, you can see the delivered size for a typical device under ‘Release Management’ -&gt; ‘Artifact Library’:</p><figure class="rq rr rs rt ru mx nd ne paragraph-image"><div role="button" tabindex="0" class="nn no fj np bh nq"><div class="nd ne sx"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*yno3GA8adiZ14mVoxpwTVw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*yno3GA8adiZ14mVoxpwTVw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*yno3GA8adiZ14mVoxpwTVw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*yno3GA8adiZ14mVoxpwTVw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*yno3GA8adiZ14mVoxpwTVw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*yno3GA8adiZ14mVoxpwTVw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*yno3GA8adiZ14mVoxpwTVw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*yno3GA8adiZ14mVoxpwTVw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*yno3GA8adiZ14mVoxpwTVw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*yno3GA8adiZ14mVoxpwTVw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*yno3GA8adiZ14mVoxpwTVw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*yno3GA8adiZ14mVoxpwTVw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*yno3GA8adiZ14mVoxpwTVw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*yno3GA8adiZ14mVoxpwTVw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh me nr c" width="700" height="343" loading="lazy" role="presentation"/></picture></div></div><figcaption class="ry ff rz nd ne sa sb bf b bg z du">And the survey says…</figcaption></figure><p id="f9a2" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">You can see that we hit our 10MB goal and then some, with a download size of only <strong class="nu gv">9.21MB</strong>! Compared to the 2017 app, at 60MB, we’ve managed to reduce the size by <strong class="nu gv">85%</strong>! 🎉🎆</p><figure class="rq rr rs rt ru mx nd ne paragraph-image"><div role="button" tabindex="0" class="nn no fj np bh nq"><div class="nd ne sy"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*UT_XNkjswxZIyvLT2l-nyg.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*UT_XNkjswxZIyvLT2l-nyg.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*UT_XNkjswxZIyvLT2l-nyg.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*UT_XNkjswxZIyvLT2l-nyg.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*UT_XNkjswxZIyvLT2l-nyg.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*UT_XNkjswxZIyvLT2l-nyg.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*UT_XNkjswxZIyvLT2l-nyg.gif 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*UT_XNkjswxZIyvLT2l-nyg.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*UT_XNkjswxZIyvLT2l-nyg.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*UT_XNkjswxZIyvLT2l-nyg.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*UT_XNkjswxZIyvLT2l-nyg.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*UT_XNkjswxZIyvLT2l-nyg.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*UT_XNkjswxZIyvLT2l-nyg.gif 1100w, https://miro.medium.com/v2/resize:fit:1400/1*UT_XNkjswxZIyvLT2l-nyg.gif 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh me nr c" width="700" height="394" loading="lazy" role="presentation"/></picture></div></div><figcaption class="ry ff rz nd ne sa sb bf b bg z du">Actual footage from Santa HQ</figcaption></figure><h2 id="11ee" class="sc pv gu bf pw sd se dy qa sf sg ea qe od sh si sj oh sk sl sm ol sn so sp sq bk">Benefits for all</h2><p id="2598" class="pw-post-body-paragraph ns nt gu nu b nv qs nx ny nz qt ob oc od qu of og oh qv oj ok ol qw on oo op gn bk">Hopefully this post has shown you that moving to App Bundles can have massive benefits for your users. Yes, it can be a non-trivial amount of work to split out all of your modules, but the benefits of that work also enforce good code practices like cohesive and decoupled modules.</p><p id="b5de" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk">One small caveat to the numbers above is that they also contain the results of the other size reduction techniques we used, including asset compression and moving to R8. We will discuss this more in the next blog post.</p></div></div></div><div class="ab cb or os ot ou" role="separator"><span class="ov by bm ow ox oy"></span><span class="ov by bm ow ox oy"></span><span class="ov by bm ow ox"></span></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><p id="8057" class="pw-post-body-paragraph ns nt gu nu b nv nw nx ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op gn bk"><em class="oq">*You might be wondering why 26 hours instead of 24? This is because the International date line </em><a class="af oz" href="https://en.wikipedia.org/wiki/International_Date_Line#/media/File:International_Date_Line.png" rel="noopener ugc nofollow" target="_blank"><em class="oq">is not a straight line</em></a><em class="oq">. Kiribati has a timezone of </em><a class="af oz" href="https://www.timeanddate.com/worldclock/difference.html?p1=274" rel="noopener ugc nofollow" target="_blank"><em class="oq">UTC+14</em></a><em class="oq">, which means a 26 hour time difference to Howland and Baker Islands, which use UTC-12.</em></p></div></div></div></div></section></div></div></article></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="sz ta ab ja"><div class="pm ab"><a class="tb ay am ao" rel="noopener follow" href="/tag/android?source=post_page-----dde180716096--------------------------------"><div class="tc fj cx td ge te tf bf b bg z bk tg">Android</div></a></div><div class="pm ab"><a class="tb ay am ao" rel="noopener follow" href="/tag/android-app-bundle?source=post_page-----dde180716096--------------------------------"><div class="tc fj cx td ge te tf bf b bg z bk tg">Android App Bundle</div></a></div><div class="pm ab"><a class="tb ay am ao" rel="noopener follow" href="/tag/android-app-development?source=post_page-----dde180716096--------------------------------"><div class="tc fj cx td ge te tf bf b bg z bk tg">Android App Development</div></a></div></div></div></div><div class="l"></div><footer class="th ti tj tk tl tm tn to tp ab q tq ik c"><div class="l ae"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ab cp tr"><div class="ab q kv"><div class="ts l"><span class="l tt tu tv e d"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fandroiddevelopers%2Fdde180716096&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fandroiddevelopers%2Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096&amp;user=Chris+Banes&amp;userId=9303277cb6db&amp;source=---footer_actions--dde180716096---------------------clap_footer-----------"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></span><span class="l h g f tw tx"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fandroiddevelopers%2Fdde180716096&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fandroiddevelopers%2Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096&amp;user=Chris+Banes&amp;userId=9303277cb6db&amp;source=---footer_actions--dde180716096---------------------clap_footer-----------"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></span></div><div class="bq ab"><div><div class="bm" aria-hidden="false"><button class="ao la ls lt ab q fk lu lv" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lr"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg><p class="bf b bg z du"><span class="pw-responses-count lq lr">1</span></p></button></div></div></div></div><div class="ab q"><div class="oy l ix"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2Fdde180716096&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fandroiddevelopers%2Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096&amp;source=---footer_actions--dde180716096---------------------bookmark_footer-----------"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lx" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="oy l ix"><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="footerSocialShareButton" class="af fk ah ai aj ak al mf an ao ap ex mg mh lv mi"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg></button></div></div></div></div></div></div></div></div></div></footer><div class="ty tz ua ub uc l bx"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ud l"><div class="ab ue uf ug iz iy"><div class="uh ui uj uk ul um un uo up uq ab cp"><div class="h k"><a href="https://medium.com/androiddevelopers?source=post_page---post_publication_info--dde180716096--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Android Developers" class="ur ib ic cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*4Tg6pPzer7cIarYaszIKaQ.png" width="48" height="48" loading="lazy"/><div class="ur l ic ib fs n fr us"></div></div></a></div><div class="j i d"><a href="https://medium.com/androiddevelopers?source=post_page---post_publication_info--dde180716096--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Android Developers" class="ur uu ut cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*4Tg6pPzer7cIarYaszIKaQ.png" width="64" height="64" loading="lazy"/><div class="ur l ut uu fs n fr us"></div></div></a></div><div class="j i d uv ix"><div class="ab"></div></div></div><div class="ab co pi"><div class="uw ux uy mz my l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" href="https://medium.com/androiddevelopers?source=post_page---post_publication_info--dde180716096--------------------------------" rel="noopener follow"><h2 class="pw-author-name bf va vb vc vd ve vf vg od si sj oh sl sm ol so sp bk"><span class="gn uz">Published in <!-- -->Android Developers</span></h2></a><div class="pm ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/androiddevelopers/followers?source=post_page---post_publication_info--dde180716096--------------------------------">51K Followers</a></span></div><div class="bf b bg z du ab jd"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/androiddevelopers/test-smarter-not-harder-new-testing-strategies-documentation-255973814ae3?source=post_page---post_publication_info--dde180716096--------------------------------">Last published <!-- -->1 day ago</a></div></div><div class="vh l"><p class="bf b bg z bk"><span class="gn">Articles on modern tools and resources to help you build experiences that people love, faster and easier, across every Android device.</span></p></div></div></div><div class="h k"><div class="ab"></div></div></div></div><div class="ab ue uf ug iz iy"><div class="uh ui uj uk ul um un uo up uq ab cp"><div class="h k"><a tabindex="0" rel="noopener follow" href="/@chrisbanes?source=post_page---post_author_info--dde180716096--------------------------------"><div class="l fj"><img alt="Chris Banes" class="l fd by ic ib cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*ik17e6aHCcc160bYFl-Evg.jpeg" width="48" height="48" loading="lazy"/><div class="fr by l ic ib fs n ay us"></div></div></a></div><div class="j i d"><a tabindex="0" rel="noopener follow" href="/@chrisbanes?source=post_page---post_author_info--dde180716096--------------------------------"><div class="l fj"><img alt="Chris Banes" class="l fd by ut uu cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*ik17e6aHCcc160bYFl-Evg.jpeg" width="64" height="64" loading="lazy"/><div class="fr by l ut uu fs n ay us"></div></div></a></div><div class="j i d uv ix"><div class="ab"><span><button class="bf b bg z vi tc vj vk vl vm vn ev ew vo vp vq fa fb fc fd bm fe ff">Follow</button></span></div></div></div><div class="ab co pi"><div class="uw ux uy mz my l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" rel="noopener follow" href="/@chrisbanes?source=post_page---post_author_info--dde180716096--------------------------------"><h2 class="pw-author-name bf va vb vc vd ve vf vg od si sj oh sl sm ol so sp bk"><span class="gn uz">Written by <!-- -->Chris Banes</span></h2></a><div class="pm ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/@chrisbanes/followers?source=post_page---post_author_info--dde180716096--------------------------------">10.7K Followers</a></span></div><div class="bf b bg z du ab jd"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/@chrisbanes/following?source=post_page---post_author_info--dde180716096--------------------------------">85 Following</a></div></div><div class="vh l"><p class="bf b bg z bk"><span class="gn">Work at CashApp on #Android</span></p></div></div></div><div class="h k"><div class="ab"><span><button class="bf b bg z vi tc vj vk vl vm vn ev ew vo vp vq fa fb fc fd bm fe ff">Follow</button></span></div></div></div><div class="vr bh vs vt"></div></div></div><div class="h k j"><div class="vr bh vs vu"></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="vv ab kv ja"><div class="vw vx l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://help.medium.com/hc/en-us?source=post_page-----dde180716096--------------------------------" rel="noopener follow"><p class="bf b dv z du">Help</p></a></div><div class="vw vx l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.statuspage.io/?source=post_page-----dde180716096--------------------------------" rel="noopener follow"><p class="bf b dv z du">Status</p></a></div><div class="vw vx l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/about?autoplay=1&amp;source=post_page-----dde180716096--------------------------------"><p class="bf b dv z du">About</p></a></div><div class="vw vx l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/jobs-at-medium/work-at-medium-959d1a85284e?source=post_page-----dde180716096--------------------------------"><p class="bf b dv z du">Careers</p></a></div><div class="vw vx l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="pressinquiries@medium.com?source=post_page-----dde180716096--------------------------------" rel="noopener follow"><p class="bf b dv z du">Press</p></a></div><div class="vw vx l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://blog.medium.com/?source=post_page-----dde180716096--------------------------------" rel="noopener follow"><p class="bf b dv z du">Blog</p></a></div><div class="vw vx l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-privacy-policy-f03bf92035c9?source=post_page-----dde180716096--------------------------------" rel="noopener follow"><p class="bf b dv z du">Privacy</p></a></div><div class="vw vx l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----dde180716096--------------------------------" rel="noopener follow"><p class="bf b dv z du">Terms</p></a></div><div class="vw vx l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://speechify.com/medium?source=post_page-----dde180716096--------------------------------" rel="noopener follow"><p class="bf b dv z du">Text to speech</p></a></div><div class="vw l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/business?source=post_page-----dde180716096--------------------------------"><p class="bf b dv z du">Teams</p></a></div></div></div></div></div></div></div></div></div></div><script>window.__BUILD_ID__="main-20241122-185319-7bcdc08639"</script><script>window.__GRAPHQL_URI__ = "https://medium.com/_/graphql"</script><script>window.__PRELOADED_STATE__ = {"algolia":{"queries":{}},"cache":{"experimentGroupSet":true,"reason":"","group":"enabled","tags":["group-edgeCachePosts","post-dde180716096","user-9303277cb6db","collection-95b274b437c2"],"serverVariantState":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","middlewareEnabled":true,"cacheStatus":"DYNAMIC","shouldUseCache":true,"vary":[],"lohpSummerUpsellEnabled":false,"publicationHierarchyEnabledWeb":false,"postBottomResponsesEnabled":false},"client":{"hydrated":false,"isUs":false,"isNativeMedium":false,"isSafariMobile":false,"isSafari":false,"isFirefox":false,"routingEntity":{"type":"DEFAULT","explicit":false},"viewerIsBot":false},"debug":{"requestId":"10fe0d1c-61d6-4079-b2c4-0799283aa75f","hybridDevServices":[],"originalSpanCarrier":{"traceparent":"00-e3b4239c92a547122f7e488209ec4656-febcbacb1b4fbb62-01"}},"multiVote":{"clapsPerPost":{}},"navigation":{"branch":{"show":null,"hasRendered":null,"blockedByCTA":false},"hideGoogleOneTap":false,"hasRenderedAlternateUserBanner":null,"currentLocation":"https:\u002F\u002Fmedium.com\u002Fandroiddevelopers\u002Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096","host":"medium.com","hostname":"medium.com","referrer":"","hasSetReferrer":false,"susiModal":{"step":null,"operation":"register"},"postRead":false,"partnerProgram":{"selectedCountryCode":null},"queryString":"","currentHash":""},"config":{"nodeEnv":"production","version":"main-20241122-185319-7bcdc08639","target":"production","productName":"Medium","publicUrl":"https:\u002F\u002Fcdn-client.medium.com\u002Flite","authDomain":"medium.com","authGoogleClientId":"216296035834-k1k6qe060s2tp2a2jam4ljdcms00sttg.apps.googleusercontent.com","favicon":"production","glyphUrl":"https:\u002F\u002Fglyph.medium.com","branchKey":"key_live_ofxXr2qTrrU9NqURK8ZwEhknBxiI6KBm","algolia":{"appId":"MQ57UUUQZ2","apiKeySearch":"394474ced050e3911ae2249ecc774921","indexPrefix":"medium_","host":"-dsn.algolia.net"},"recaptchaKey":"6Lfc37IUAAAAAKGGtC6rLS13R1Hrw_BqADfS1LRk","recaptcha3Key":"6Lf8R9wUAAAAABMI_85Wb8melS7Zj6ziuf99Yot5","recaptchaEnterpriseKeyId":"6Le-uGgpAAAAAPprRaokM8AKthQ9KNGdoxaGUvVp","datadog":{"applicationId":"6702d87d-a7e0-42fe-bbcb-95b469547ea0","clientToken":"pub853ea8d17ad6821d9f8f11861d23dfed","rumToken":"pubf9cc52896502b9413b68ba36fc0c7162","context":{"deployment":{"target":"production","tag":"main-20241122-185319-7bcdc08639","commit":"7bcdc08639c179dc5172558201a3fd3abc1b5db6"}},"datacenter":"us"},"googleAnalyticsCode":"G-7JY7T788PK","googlePay":{"apiVersion":"2","apiVersionMinor":"0","merchantId":"BCR2DN6TV7EMTGBM","merchantName":"Medium","instanceMerchantId":"13685562959212738550"},"applePay":{"version":3},"signInWallCustomDomainCollectionIds":["3a8144eabfe3","336d898217ee","61061eb0c96b","138adf9c44c","819cc2aaeee0"],"mediumMastodonDomainName":"me.dm","mediumOwnedAndOperatedCollectionIds":["8a9336e5bb4","b7e45b22fec3","193b68bd4fba","8d6b8a439e32","54c98c43354d","3f6ecf56618","d944778ce714","92d2092dc598","ae2a65f35510","1285ba81cada","544c7006046e","fc8964313712","40187e704f1c","88d9857e584e","7b6769f2748b","bcc38c8f6edf","cef6983b292","cb8577c9149e","444d13b52878","713d7dbc99b0","ef8e90590e66","191186aaafa0","55760f21cdc5","9dc80918cc93","bdc4052bbdba","8ccfed20cbb2"],"tierOneDomains":["medium.com","thebolditalic.com","arcdigital.media","towardsdatascience.com","uxdesign.cc","codeburst.io","psiloveyou.xyz","writingcooperative.com","entrepreneurshandbook.co","prototypr.io","betterhumans.coach.me","theascent.pub"],"topicsToFollow":["d61cf867d93f","8a146bc21b28","1eca0103fff3","4d562ee63426","aef1078a3ef5","e15e46793f8d","6158eb913466","55f1c20aba7a","3d18b94f6858","4861fee224fd","63c6f1f93ee","1d98b3a9a871","decb52b64abf","ae5d4995e225","830cded25262"],"topicToTagMappings":{"accessibility":"accessibility","addiction":"addiction","android-development":"android-development","art":"art","artificial-intelligence":"artificial-intelligence","astrology":"astrology","basic-income":"basic-income","beauty":"beauty","biotech":"biotech","blockchain":"blockchain","books":"books","business":"business","cannabis":"cannabis","cities":"cities","climate-change":"climate-change","comics":"comics","coronavirus":"coronavirus","creativity":"creativity","cryptocurrency":"cryptocurrency","culture":"culture","cybersecurity":"cybersecurity","data-science":"data-science","design":"design","digital-life":"digital-life","disability":"disability","economy":"economy","education":"education","equality":"equality","family":"family","feminism":"feminism","fiction":"fiction","film":"film","fitness":"fitness","food":"food","freelancing":"freelancing","future":"future","gadgets":"gadgets","gaming":"gaming","gun-control":"gun-control","health":"health","history":"history","humor":"humor","immigration":"immigration","ios-development":"ios-development","javascript":"javascript","justice":"justice","language":"language","leadership":"leadership","lgbtqia":"lgbtqia","lifestyle":"lifestyle","machine-learning":"machine-learning","makers":"makers","marketing":"marketing","math":"math","media":"media","mental-health":"mental-health","mindfulness":"mindfulness","money":"money","music":"music","neuroscience":"neuroscience","nonfiction":"nonfiction","outdoors":"outdoors","parenting":"parenting","pets":"pets","philosophy":"philosophy","photography":"photography","podcasts":"podcast","poetry":"poetry","politics":"politics","privacy":"privacy","product-management":"product-management","productivity":"productivity","programming":"programming","psychedelics":"psychedelics","psychology":"psychology","race":"race","relationships":"relationships","religion":"religion","remote-work":"remote-work","san-francisco":"san-francisco","science":"science","self":"self","self-driving-cars":"self-driving-cars","sexuality":"sexuality","social-media":"social-media","society":"society","software-engineering":"software-engineering","space":"space","spirituality":"spirituality","sports":"sports","startups":"startup","style":"style","technology":"technology","transportation":"transportation","travel":"travel","true-crime":"true-crime","tv":"tv","ux":"ux","venture-capital":"venture-capital","visual-design":"visual-design","work":"work","world":"world","writing":"writing"},"defaultImages":{"avatar":{"imageId":"1*dmbNkD5D-u45r44go_cf0g.png","height":150,"width":150},"orgLogo":{"imageId":"7*V1_7XP4snlmqrc_0Njontw.png","height":110,"width":500},"postLogo":{"imageId":"bd978bb536350a710e8efb012513429cabdc4c28700604261aeda246d0f980b7","height":810,"width":1440},"postPreviewImage":{"imageId":"1*hn4v1tCaJy7cWMyb0bpNpQ.png","height":386,"width":579}},"collectionStructuredData":{"8d6b8a439e32":{"name":"Elemental","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F980\u002F1*9ygdqoKprhwuTVKUM0DLPA@2x.png","width":980,"height":159}}},"3f6ecf56618":{"name":"Forge","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F596\u002F1*uULpIlImcO5TDuBZ6lm7Lg@2x.png","width":596,"height":183}}},"ae2a65f35510":{"name":"GEN","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F264\u002F1*RdVZMdvfV3YiZTw6mX7yWA.png","width":264,"height":140}}},"88d9857e584e":{"name":"LEVEL","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*JqYMhNX6KNNb2UlqGqO2WQ.png","width":540,"height":108}}},"7b6769f2748b":{"name":"Marker","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F383\u002F1*haCUs0wF6TgOOvfoY-jEoQ@2x.png","width":383,"height":92}}},"444d13b52878":{"name":"OneZero","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*cw32fIqCbRWzwJaoQw6BUg.png","width":540,"height":123}}},"8ccfed20cbb2":{"name":"Zora","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*tZUQqRcCCZDXjjiZ4bDvgQ.png","width":540,"height":106}}}},"embeddedPostIds":{"coronavirus":"cd3010f9d81f"},"sharedCdcMessaging":{"COVID_APPLICABLE_TAG_SLUGS":[],"COVID_APPLICABLE_TOPIC_NAMES":[],"COVID_APPLICABLE_TOPIC_NAMES_FOR_TOPIC_PAGE":[],"COVID_MESSAGES":{"tierA":{"text":"For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":66,"end":73,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"tierB":{"text":"Anyone can publish on Medium per our Policies, but we don’t fact-check every story. For more info about the coronavirus, see cdc.gov.","markups":[{"start":37,"end":45,"href":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Fcategories\u002F201931128-Policies-Safety"},{"start":125,"end":132,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"paywall":{"text":"This article has been made free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":56,"end":70,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":138,"end":145,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"unbound":{"text":"This article is free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":45,"end":59,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":127,"end":134,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]}},"COVID_BANNER_POST_ID_OVERRIDE_WHITELIST":["3b31a67bff4a"]},"sharedVoteMessaging":{"TAGS":["politics","election-2020","government","us-politics","election","2020-presidential-race","trump","donald-trump","democrats","republicans","congress","republican-party","democratic-party","biden","joe-biden","maga"],"TOPICS":["politics","election"],"MESSAGE":{"text":"Find out more about the U.S. election results here.","markups":[{"start":46,"end":50,"href":"https:\u002F\u002Fcookpolitical.com\u002F2020-national-popular-vote-tracker"}]},"EXCLUDE_POSTS":["397ef29e3ca5"]},"embedPostRules":[],"recircOptions":{"v1":{"limit":3},"v2":{"limit":8}},"braintreeClientKey":"production_zjkj96jm_m56f8fqpf7ngnrd4","braintree":{"enabled":true,"merchantId":"m56f8fqpf7ngnrd4","merchantAccountId":{"usd":"AMediumCorporation_instant","eur":"amediumcorporation_EUR","cad":"amediumcorporation_CAD"},"publicKey":"ds2nn34bg2z7j5gd","braintreeEnvironment":"production","dashboardUrl":"https:\u002F\u002Fwww.braintreegateway.com\u002Fmerchants","gracePeriodDurationInDays":14,"mediumMembershipPlanId":{"monthly":"ce105f8c57a3","monthlyV2":"e8a5e126-792b-4ee6-8fba-d574c1b02fc5","monthlyWithTrial":"d5ee3dbe3db8","monthlyPremium":"fa741a9b47a2","yearly":"a40ad4a43185","yearlyV2":"3815d7d6-b8ca-4224-9b8c-182f9047866e","yearlyStaff":"d74fb811198a","yearlyWithTrial":"b3bc7350e5c7","yearlyPremium":"e21bd2c12166","monthlyOneYearFree":"e6c0637a-2bad-4171-ab4f-3c268633d83c","monthly25PercentOffFirstYear":"235ecc62-0cdb-49ae-9378-726cd21c504b","monthly20PercentOffFirstYear":"ba518864-9c13-4a99-91ca-411bf0cac756","monthly15PercentOffFirstYear":"594c029b-9f89-43d5-88f8-8173af4e070e","monthly10PercentOffFirstYear":"c6c7bc9a-40f2-4b51-8126-e28511d5bdb0","monthlyForStudents":"629ebe51-da7d-41fd-8293-34cd2f2030a8","yearlyOneYearFree":"78ba7be9-0d9f-4ece-aa3e-b54b826f2bf1","yearly25PercentOffFirstYear":"2dbb010d-bb8f-4eeb-ad5c-a08509f42d34","yearly20PercentOffFirstYear":"47565488-435b-47f8-bf93-40d5fbe0ebc8","yearly15PercentOffFirstYear":"8259809b-0881-47d9-acf7-6c001c7f720f","yearly10PercentOffFirstYear":"9dd694fb-96e1-472c-8d9e-3c868d5c1506","yearlyForStudents":"e29345ef-ab1c-4234-95c5-70e50fe6bc23","monthlyCad":"p52orjkaceei","yearlyCad":"h4q9g2up9ktt"},"braintreeDiscountId":{"oneMonthFree":"MONTHS_FREE_01","threeMonthsFree":"MONTHS_FREE_03","sixMonthsFree":"MONTHS_FREE_06","fiftyPercentOffOneYear":"FIFTY_PERCENT_OFF_ONE_YEAR"},"3DSecureVersion":"2","defaultCurrency":"usd","providerPlanIdCurrency":{"4ycw":"usd","rz3b":"usd","3kqm":"usd","jzw6":"usd","c2q2":"usd","nnsw":"usd","q8qw":"usd","d9y6":"usd","fx7w":"cad","nwf2":"cad"}},"paypalClientId":"AXj1G4fotC2GE8KzWX9mSxCH1wmPE3nJglf4Z2ig_amnhvlMVX87otaq58niAg9iuLktVNF_1WCMnN7v","paypal":{"host":"https:\u002F\u002Fapi.paypal.com:443","clientMode":"production","serverMode":"live","webhookId":"4G466076A0294510S","monthlyPlan":{"planId":"P-9WR0658853113943TMU5FDQA","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlan":{"planId":"P-7N8963881P8875835MU5JOPQ","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oneYearGift":{"name":"Medium Membership (1 Year, Digital Gift Code)","description":"Unlimited access to the best and brightest stories on Medium. Gift codes can be redeemed at medium.com\u002Fredeem.","price":"50.00","currency":"USD","sku":"membership-gift-1-yr"},"oldMonthlyPlan":{"planId":"P-96U02458LM656772MJZUVH2Y","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlan":{"planId":"P-59P80963JF186412JJZU3SMI","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"monthlyPlanWithTrial":{"planId":"P-66C21969LR178604GJPVKUKY","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlanWithTrial":{"planId":"P-6XW32684EX226940VKCT2MFA","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oldMonthlyPlanNoSetupFee":{"planId":"P-4N046520HR188054PCJC7LJI","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlanNoSetupFee":{"planId":"P-7A4913502Y5181304CJEJMXQ","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"sdkUrl":"https:\u002F\u002Fwww.paypal.com\u002Fsdk\u002Fjs"},"stripePublishableKey":"pk_live_7FReX44VnNIInZwrIIx6ghjl","log":{"json":true,"level":"info"},"imageUploadMaxSizeMb":25,"staffPicks":{"title":"Staff Picks","catalogId":"c7bc6e1ee00f"}},"session":{"xsrf":""}}</script><script>window.__APOLLO_STATE__ = {"ROOT_QUERY":{"__typename":"Query","collectionByDomainOrSlug({\"domainOrSlug\":\"androiddevelopers\"})":{"__ref":"Collection:95b274b437c2"},"viewer":null,"postResult({\"id\":\"dde180716096\"})":{"__ref":"Post:dde180716096"}},"ImageMetadata:":{"__typename":"ImageMetadata","id":""},"Collection:95b274b437c2":{"__typename":"Collection","id":"95b274b437c2","favicon":{"__ref":"ImageMetadata:"},"customStyleSheet":null,"colorPalette":{"__typename":"ColorPalette","highlightSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FFF4F2F3","point":0},{"__typename":"ColorPoint","color":"#FFF2F0F1","point":0.1},{"__typename":"ColorPoint","color":"#FFF0EEEF","point":0.2},{"__typename":"ColorPoint","color":"#FFEEECEE","point":0.3},{"__typename":"ColorPoint","color":"#FFECEAEC","point":0.4},{"__typename":"ColorPoint","color":"#FFEAE8EA","point":0.5},{"__typename":"ColorPoint","color":"#FFE8E7E9","point":0.6},{"__typename":"ColorPoint","color":"#FFE6E5E7","point":0.7},{"__typename":"ColorPoint","color":"#FFE4E3E5","point":0.8},{"__typename":"ColorPoint","color":"#FFE2E1E4","point":0.9},{"__typename":"ColorPoint","color":"#FFE0DFE2","point":1}]},"defaultBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FF848488","point":0},{"__typename":"ColorPoint","color":"#FF7B7B7E","point":0.1},{"__typename":"ColorPoint","color":"#FF717275","point":0.2},{"__typename":"ColorPoint","color":"#FF68686B","point":0.3},{"__typename":"ColorPoint","color":"#FF5E5E60","point":0.4},{"__typename":"ColorPoint","color":"#FF545456","point":0.5},{"__typename":"ColorPoint","color":"#FF4A494B","point":0.6},{"__typename":"ColorPoint","color":"#FF3F3E40","point":0.7},{"__typename":"ColorPoint","color":"#FF333334","point":0.8},{"__typename":"ColorPoint","color":"#FF272728","point":0.9},{"__typename":"ColorPoint","color":"#FF1A1A1A","point":1}]},"tintBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FF202124","colorPoints":[{"__typename":"ColorPoint","color":"#FF202124","point":0},{"__typename":"ColorPoint","color":"#FF3D3E41","point":0.1},{"__typename":"ColorPoint","color":"#FF58585B","point":0.2},{"__typename":"ColorPoint","color":"#FF707073","point":0.3},{"__typename":"ColorPoint","color":"#FF878689","point":0.4},{"__typename":"ColorPoint","color":"#FF9D9C9E","point":0.5},{"__typename":"ColorPoint","color":"#FFB2B1B2","point":0.6},{"__typename":"ColorPoint","color":"#FFC6C5C6","point":0.7},{"__typename":"ColorPoint","color":"#FFDAD8DA","point":0.8},{"__typename":"ColorPoint","color":"#FFEEEBEC","point":0.9},{"__typename":"ColorPoint","color":"#FFFFFEFF","point":1}]}},"domain":null,"slug":"androiddevelopers","googleAnalyticsId":null,"editors":[{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:e1f26db83092"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:2e0fc9a4a8c2"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:d5885adb1ddf"}}],"name":"Android Developers","avatar":{"__ref":"ImageMetadata:1*4Tg6pPzer7cIarYaszIKaQ.png"},"description":"Articles on modern tools and resources to help you build experiences that people love, faster and easier, across every Android device.","subscriberCount":51942,"latestPostsConnection({\"paging\":{\"limit\":1}})":{"__typename":"PostConnection","posts":[{"__ref":"Post:255973814ae3"}]},"viewerEdge":{"__ref":"CollectionViewerEdge:collectionId:95b274b437c2-viewerId:lo_55aa09782afd"},"twitterUsername":"androiddev","facebookPageId":null,"logo":{"__ref":"ImageMetadata:1*5pMw_nx55x_66tk77kutPQ.png"}},"User:e1f26db83092":{"__typename":"User","id":"e1f26db83092"},"User:2e0fc9a4a8c2":{"__typename":"User","id":"2e0fc9a4a8c2"},"User:d5885adb1ddf":{"__typename":"User","id":"d5885adb1ddf"},"ImageMetadata:1*4Tg6pPzer7cIarYaszIKaQ.png":{"__typename":"ImageMetadata","id":"1*4Tg6pPzer7cIarYaszIKaQ.png"},"User:e0a4c9469bb5":{"__typename":"User","id":"e0a4c9469bb5","customDomainState":null,"hasSubdomain":false,"username":"JoseAlcerreca"},"Post:255973814ae3":{"__typename":"Post","id":"255973814ae3","firstPublishedAt":1732208584164,"creator":{"__ref":"User:e0a4c9469bb5"},"collection":{"__ref":"Collection:95b274b437c2"},"isSeries":false,"mediumUrl":"https:\u002F\u002Fmedium.com\u002Fandroiddevelopers\u002Ftest-smarter-not-harder-new-testing-strategies-documentation-255973814ae3","sequence":null,"uniqueSlug":"test-smarter-not-harder-new-testing-strategies-documentation-255973814ae3"},"LinkedAccounts:9303277cb6db":{"__typename":"LinkedAccounts","mastodon":null,"id":"9303277cb6db"},"UserViewerEdge:userId:9303277cb6db-viewerId:lo_55aa09782afd":{"__typename":"UserViewerEdge","id":"userId:9303277cb6db-viewerId:lo_55aa09782afd","isFollowing":false,"isUser":false,"isMuting":false},"NewsletterV3:3ec07c1dfcb":{"__typename":"NewsletterV3","id":"3ec07c1dfcb","type":"NEWSLETTER_TYPE_AUTHOR","slug":"9303277cb6db","name":"9303277cb6db","collection":null,"user":{"__ref":"User:9303277cb6db"}},"User:9303277cb6db":{"__typename":"User","id":"9303277cb6db","name":"Chris Banes","username":"chrisbanes","newsletterV3":{"__ref":"NewsletterV3:3ec07c1dfcb"},"linkedAccounts":{"__ref":"LinkedAccounts:9303277cb6db"},"isSuspended":false,"imageId":"1*ik17e6aHCcc160bYFl-Evg.jpeg","mediumMemberAt":0,"verifications":{"__typename":"VerifiedInfo","isBookAuthor":false},"socialStats":{"__typename":"SocialStats","followerCount":10722,"followingCount":81,"collectionFollowingCount":4},"customDomainState":{"__typename":"CustomDomainState","live":{"__typename":"CustomDomain","domain":"chrisbanes.medium.com"}},"hasSubdomain":true,"bio":"Work at CashApp on #Android","isPartnerProgramEnrolled":false,"viewerEdge":{"__ref":"UserViewerEdge:userId:9303277cb6db-viewerId:lo_55aa09782afd"},"viewerIsUser":false,"postSubscribeMembershipUpsellShownAt":0,"membership":null,"allowNotes":true,"twitterScreenName":"chrisbanes"},"Topic:64756708407c":{"__typename":"Topic","slug":"android-development","id":"64756708407c","name":"Android Dev"},"Paragraph:c1901b16f442_0":{"__typename":"Paragraph","id":"c1901b16f442_0","name":"d6d2","type":"H3","href":null,"layout":null,"metadata":null,"text":"Google Santa Tracker — moving to an Android App Bundle","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*ksxyyNT2V-A2N626DZ9D7A.png":{"__typename":"ImageMetadata","id":"1*ksxyyNT2V-A2N626DZ9D7A.png","originalHeight":888,"originalWidth":2120,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:c1901b16f442_1":{"__typename":"Paragraph","id":"c1901b16f442_1","name":"45d6","type":"IMG","href":null,"layout":"OUTSET_CENTER","metadata":{"__ref":"ImageMetadata:1*ksxyyNT2V-A2N626DZ9D7A.png"},"text":"","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_2":{"__typename":"Paragraph","id":"c1901b16f442_2","name":"4b52","type":"P","href":null,"layout":null,"metadata":null,"text":"This post is the first in the series which explores the improvements made to the Google Santa Tracker Android app for 2018.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":123,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_3":{"__typename":"Paragraph","id":"c1901b16f442_3","name":"c498","type":"P","href":null,"layout":null,"metadata":null,"text":"Santa Tracker is an app which Google releases every year, allowing users to track Santa as he makes his way around the globe. Unfortunately Santa Tracker has drastically grown in size over the years, resulting in a hefty 60MB download size in 2017. Our goal for the recent holiday season was to drastically reduce that, and this post talks through how we did that.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":221,"end":225,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_4":{"__typename":"Paragraph","id":"c1901b16f442_4","name":"665e","type":"P","href":null,"layout":null,"metadata":null,"text":"If you’ve used the Google Santa Tracker Android app you’ll know that it has two main features, the “Tracker” which allows users to track Santa as he makes his journey across the globe, and a collection of mini-games which are available to play throughout December, designed to help users to get into the holiday spirit 🎄.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":19,"end":51,"href":"https:\u002F\u002Fplay.google.com\u002Fstore\u002Fapps\u002Fdetails?id=com.google.android.apps.santatracker","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_5":{"__typename":"Paragraph","id":"c1901b16f442_5","name":"dade","type":"P","href":null,"layout":null,"metadata":null,"text":"The “Tracker” is the primary feature of the app and is where most of our usage comes from. The feature is actually only available for the 26 hours* before Christmas (December 24th), and during that time the tracker is the most used feature. To give you an idea of numbers, 37% of all screen views (during December) happened on the 24th December, and over 65% of screen views on that day were on the tracker.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":273,"end":276,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":355,"end":358,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_6":{"__typename":"Paragraph","id":"c1901b16f442_6","name":"a0ff","type":"P","href":null,"layout":null,"metadata":null,"text":"So why is this important? Knowing what our primary feature was allowed us to think about what parts of the app were critical in the initial install, and which parts were secondary and could potentially be split out into separate modules which could be dynamically installed, making our initial install smaller. The 2017 app was released as a single APK which contained everything, including all of the games, even if the user did not play them.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_7":{"__typename":"Paragraph","id":"c1901b16f442_7","name":"2b18","type":"P","href":null,"layout":null,"metadata":null,"text":"We knew it was time for Santa Tracker to go on a diet, so we set a goal of shrinking our initial download size down to just 10MB 😥.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":119,"end":123,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_8":{"__typename":"Paragraph","id":"c1901b16f442_8","name":"05ad","type":"P","href":null,"layout":null,"metadata":null,"text":"Why that size you ask? Well it is shown to have a 30% higher conversion rate than a 100MB sized app. Santa Tracker is not an app where we track conversion rate but a lot of apps do. 10MB was also a very low goal to try and achieve, to see if it was even possible. For more info on the stats behind this, read this article from the Google Play team:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":331,"end":347,"href":"https:\u002F\u002Fmedium.com\u002Fgoogleplaydev","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_9":{"__typename":"Paragraph","id":"c1901b16f442_9","name":"9a2f","type":"MIXTAPE_EMBED","href":null,"layout":null,"metadata":null,"text":"Shrinking APKs, growing installs\nHow your app’s APK size impacts install conversion ratesmedium.com","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":99,"href":"https:\u002F\u002Fmedium.com\u002Fgoogleplaydev\u002Fshrinking-apks-growing-installs-5d3fcba23ce2","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":0,"end":32,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":33,"end":89,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":{"__typename":"MixtapeMetadata","href":"https:\u002F\u002Fmedium.com\u002Fgoogleplaydev\u002Fshrinking-apks-growing-installs-5d3fcba23ce2","mediaResource":{"__typename":"MediaResource","mediumCatalog":null},"thumbnailImageId":"0*f1gQ1k1n3_d4-x9t."}},"Paragraph:c1901b16f442_10":{"__typename":"Paragraph","id":"c1901b16f442_10","name":"b701","type":"H3","href":null,"layout":null,"metadata":null,"text":"Dynamic Delivery","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_11":{"__typename":"Paragraph","id":"c1901b16f442_11","name":"5f74","type":"P","href":null,"layout":null,"metadata":null,"text":"You may have heard about the new Android App Bundle format, which allows the Google Play store to dynamically deliver a customized app with only the parts relevant to the device. This was an easy first step for us. By simply uploading an AAB (Android App Bundle) instead of an APK, we instantly managed to reduce the download size by nearly 20% to 48.5MB (from 60MB). That’s a huge saving for the tiny amount of work we had to do!","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":32,"end":51,"href":"https:\u002F\u002Fdeveloper.android.com\u002Fplatform\u002Ftechnology\u002Fapp-bundle\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":341,"end":344,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":348,"end":354,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":377,"end":381,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":397,"end":401,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_12":{"__typename":"Paragraph","id":"c1901b16f442_12","name":"47c5","type":"PQ","href":null,"layout":null,"metadata":null,"text":"If you only take away one thing from reading this post, make sure it is to try uploading an AAB instead of an APK for your app. The chances are high that this small change will save your users time and money.","hasDropCap":true,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_13":{"__typename":"Paragraph","id":"c1901b16f442_13","name":"d6f5","type":"P","href":null,"layout":null,"metadata":null,"text":"So how does Google Play achieve that saving? By being able to deliver something optimized for a single device, the infrastructure can remove all of the language resources, density resources, and native libraries which are not applicable for the device. Example, if your device set to fr-FR, has a xxhdpi display, with an arm64-v8a CPU, the APK delivered will only include the necessary resources, and not for example, any strings localized to Spanish. You’d be surprised at how much space things like localized strings can take up.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":284,"end":289,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":297,"end":303,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":321,"end":330,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_14":{"__typename":"Paragraph","id":"c1901b16f442_14","name":"abe3","type":"P","href":null,"layout":null,"metadata":null,"text":"Make sure to watch the ‘Optimize Your App Size’ talk from Android Dev Summit ’18 for more info:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":24,"end":46,"href":"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=QdoEcfibG-s","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":58,"end":80,"href":"https:\u002F\u002Fdeveloper.android.com\u002Fdev-summit\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"MediaResource:41e8226d84294d5a94f548f9a1cf5601":{"__typename":"MediaResource","id":"41e8226d84294d5a94f548f9a1cf5601","iframeSrc":"https:\u002F\u002Fcdn.embedly.com\u002Fwidgets\u002Fmedia.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQdoEcfibG-s%3Ffeature%3Doembed&url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQdoEcfibG-s&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQdoEcfibG-s%2Fhqdefault.jpg&key=a19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=youtube","iframeHeight":480,"iframeWidth":854,"title":"Optimize Your App Size with This One Trick (Android Dev Summit '18)"},"Paragraph:c1901b16f442_15":{"__typename":"Paragraph","id":"c1901b16f442_15","name":"ba19","type":"IFRAME","href":null,"layout":"INSET_CENTER","metadata":null,"text":"‘Optimize Your App Size’ talk from ADS ‘18","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":{"__typename":"Iframe","mediaResource":{"__ref":"MediaResource:41e8226d84294d5a94f548f9a1cf5601"}},"mixtapeMetadata":null},"Paragraph:c1901b16f442_16":{"__typename":"Paragraph","id":"c1901b16f442_16","name":"7d36","type":"H3","href":null,"layout":null,"metadata":null,"text":"Feature modules","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_17":{"__typename":"Paragraph","id":"c1901b16f442_17","name":"2668","type":"P","href":null,"layout":null,"metadata":null,"text":"While we made a good start, we were quite far away from our goal of 10MB! So we started thinking about which features of the app could be split out as dynamic feature modules, where they could be fetched on demand using the Play Core library. Luckily our app was already logically split out into nice separate chunks: the games 🎮.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":223,"end":241,"href":"https:\u002F\u002Fdeveloper.android.com\u002Fguide\u002Fapp-bundle\u002Fplaycore","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_18":{"__typename":"Paragraph","id":"c1901b16f442_18","name":"b117","type":"P","href":null,"layout":null,"metadata":null,"text":"A plan formed to convert each game into a separate feature module, and install them only when the user first chose to play that particular game. Sounds great, right? Well while logically the games were all separate, the code base was… not. It had grown over several years into a tangled heap of interdependent modules, layers of libraries modules underneath everything, and duplicate resources everywhere.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":235,"end":238,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_19":{"__typename":"Paragraph","id":"c1901b16f442_19","name":"b727","type":"P","href":null,"layout":null,"metadata":null,"text":"Our first job was to fix the tight coupling and assert some clean separation between the game modules. We painstakingly untangled all of the game modules so that each was a completely separate module, using the new com.android.dynamic-feature Gradle plugin. For any games which had shared dependencies (e.g, the ‘Penguin Swim’ and ‘Elf Jetpack’ games share a lot of code), the dependencies were added into the ‘base’ module so that they would be only installed once.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":215,"end":242,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_20":{"__typename":"Paragraph","id":"c1901b16f442_20","name":"9ae3","type":"H4","href":null,"layout":null,"metadata":null,"text":"Implementing feature modules","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_21":{"__typename":"Paragraph","id":"c1901b16f442_21","name":"7ce5","type":"P","href":null,"layout":null,"metadata":null,"text":"As discussed above, the majority of the work in moving to feature modules is actually organizing existing code, but there is still some integration which needs to be done with the Play Core library to hook it all up.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":180,"end":197,"href":"https:\u002F\u002Fdeveloper.android.com\u002Fguide\u002Fapp-bundle\u002Fplaycore","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_22":{"__typename":"Paragraph","id":"c1901b16f442_22","name":"33a2","type":"P","href":null,"layout":null,"metadata":null,"text":"First let’s talk about the UX when a user launches a game. We start a ‘splash screen’ activity, which displays the logo and title of the game, and then after a brief period it launches the game. All of the information about the game to launch is passed to the splash activity as intent extras. This behavior has been the same in the app for a number of years and wasn’t something that we wanted to change. It did however provide a very nice integration point for fetching dynamic feature modules.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_23":{"__typename":"Paragraph","id":"c1901b16f442_23","name":"85a1","type":"P","href":null,"layout":null,"metadata":null,"text":"For 2018 we updated the splash behavior so that we send four key pieces of information, the title of the game, game icon, Activity class to launch, and the ID of the feature module it is in. Once the splash activity is shown, it checks whether the relevant feature module is installed. If it is, it just launches the game as normal. If not, it requests an install via the Play Core library, displaying a progress bar indicating the ongoing download:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*KPoBN-zNlJPVmjrIy8A8jQ.gif":{"__typename":"ImageMetadata","id":"1*KPoBN-zNlJPVmjrIy8A8jQ.gif","originalHeight":625,"originalWidth":500,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:c1901b16f442_24":{"__typename":"Paragraph","id":"c1901b16f442_24","name":"dec3","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*KPoBN-zNlJPVmjrIy8A8jQ.gif"},"text":"","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_25":{"__typename":"Paragraph","id":"c1901b16f442_25","name":"1f1b","type":"P","href":null,"layout":null,"metadata":null,"text":"We found out early on in testing that you need to be careful about the conditions in which you install a feature module. We did not want to inadvertently cost the user money by installing feature modules while they were on their mobile network. To combat that we added a confirmation dialog when we detected that the device was connected to a metered network (such as a mobile network):","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*2qCP_mHG0gr4eKJ0Md0H1A.png":{"__typename":"ImageMetadata","id":"1*2qCP_mHG0gr4eKJ0Md0H1A.png","originalHeight":1146,"originalWidth":1080,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:c1901b16f442_26":{"__typename":"Paragraph","id":"c1901b16f442_26","name":"6bfa","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*2qCP_mHG0gr4eKJ0Md0H1A.png"},"text":"Confirmation dialog shown when the device is connected to a metered network","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_27":{"__typename":"Paragraph","id":"c1901b16f442_27","name":"1fb6","type":"P","href":null,"layout":null,"metadata":null,"text":"The overall logic for this looks like this:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"MediaResource:43abc345e2aa0a28e09f9fa696cf859b":{"__typename":"MediaResource","id":"43abc345e2aa0a28e09f9fa696cf859b","iframeSrc":"https:\u002F\u002Fcdn.embedly.com\u002Fwidgets\u002Fmedia.html?url=https%3A%2F%2Fpl.kotl.in%2FSJJQcdI4E&src=https%3A%2F%2Fpl.kotl.in%2FSJJQcdI4E&type=text%2Fhtml&key=a19fcc184b9711e1b4764040d3dc5c07&schema=kotl","iframeHeight":300,"iframeWidth":800,"title":"Kotlin Playground"},"Paragraph:c1901b16f442_28":{"__typename":"Paragraph","id":"c1901b16f442_28","name":"3e69","type":"IFRAME","href":null,"layout":"INSET_CENTER","metadata":null,"text":"","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":{"__typename":"Iframe","mediaResource":{"__ref":"MediaResource:43abc345e2aa0a28e09f9fa696cf859b"}},"mixtapeMetadata":null},"Paragraph:c1901b16f442_29":{"__typename":"Paragraph","id":"c1901b16f442_29","name":"9156","type":"P","href":null,"layout":null,"metadata":null,"text":"The startModuleInstall() method is a little more complex due to how the Play Core API works. You need to attach a listener which will be invoked during an install, and then request an install, like so:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":4,"end":24,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"MediaResource:e9f1d84d6d6dab2170a60534cd56ec9f":{"__typename":"MediaResource","id":"e9f1d84d6d6dab2170a60534cd56ec9f","iframeSrc":"https:\u002F\u002Fcdn.embedly.com\u002Fwidgets\u002Fmedia.html?url=https%3A%2F%2Fpl.kotl.in%2FrypLcuLNV&src=https%3A%2F%2Fpl.kotl.in%2FrypLcuLNV&type=text%2Fhtml&key=a19fcc184b9711e1b4764040d3dc5c07&schema=kotl","iframeHeight":300,"iframeWidth":800,"title":"Kotlin Playground"},"Paragraph:c1901b16f442_30":{"__typename":"Paragraph","id":"c1901b16f442_30","name":"aaad","type":"IFRAME","href":null,"layout":"INSET_CENTER","metadata":null,"text":"","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":{"__typename":"Iframe","mediaResource":{"__ref":"MediaResource:e9f1d84d6d6dab2170a60534cd56ec9f"}},"mixtapeMetadata":null},"Paragraph:c1901b16f442_31":{"__typename":"Paragraph","id":"c1901b16f442_31","name":"b699","type":"P","href":null,"layout":null,"metadata":null,"text":"The listener will later receive an install complete signal, and finally we launch the game. You can find the complete code here.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":123,"end":127,"href":"https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fsanta-tracker-android\u002Ftree\u002Fmaster\u002Fsanta-tracker\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fgoogle\u002Fandroid\u002Fapps\u002Fsantatracker\u002Fgames\u002FSplashActivity.kt","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_32":{"__typename":"Paragraph","id":"c1901b16f442_32","name":"41ca","type":"H3","href":null,"layout":null,"metadata":null,"text":"Results","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_33":{"__typename":"Paragraph","id":"c1901b16f442_33","name":"d4a4","type":"P","href":null,"layout":null,"metadata":null,"text":"If you’ve got this far into the post you probably want to see how we did…","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_34":{"__typename":"Paragraph","id":"c1901b16f442_34","name":"7ef8","type":"P","href":null,"layout":null,"metadata":null,"text":"Android Studio has a great way to analyze your App Bundles (and APKs), to drill down and see a download size value for each feature module. Using that we can see that our initial download size is 11.6MB (missing out on our 10MB goal), and our total download size is 25.5MB.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*z6BiUOLlfqpwx58ywfSsVw.png":{"__typename":"ImageMetadata","id":"1*z6BiUOLlfqpwx58ywfSsVw.png","originalHeight":1006,"originalWidth":1826,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:c1901b16f442_35":{"__typename":"Paragraph","id":"c1901b16f442_35","name":"d85b","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*z6BiUOLlfqpwx58ywfSsVw.png"},"text":"* Download size calculated using Analyze Bundle feature in Android Studio","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":73,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*aamb-oJ9fhE-7VPpvHh-bA.png":{"__typename":"ImageMetadata","id":"1*aamb-oJ9fhE-7VPpvHh-bA.png","originalHeight":1005,"originalWidth":1796,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:c1901b16f442_36":{"__typename":"Paragraph","id":"c1901b16f442_36","name":"240d","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*aamb-oJ9fhE-7VPpvHh-bA.png"},"text":"Chart showing how the module sizes compare","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_37":{"__typename":"Paragraph","id":"c1901b16f442_37","name":"134a","type":"P","href":null,"layout":null,"metadata":null,"text":"But…. these values are only looking at the generated Android App Bundle archive, and do not take into account any savings which Google Play can provide through Dynamic Delivery (which we discussed above). The most sure way to see the download size for a particular device is by looking on the Google Play Developer Console. After uploading an App Bundle, you can see the delivered size for a typical device under ‘Release Management’ -\u003E ‘Artifact Library’:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":293,"end":322,"href":"https:\u002F\u002Fplay.google.com\u002Fapps\u002Fpublish\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*yno3GA8adiZ14mVoxpwTVw.png":{"__typename":"ImageMetadata","id":"1*yno3GA8adiZ14mVoxpwTVw.png","originalHeight":616,"originalWidth":1258,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:c1901b16f442_38":{"__typename":"Paragraph","id":"c1901b16f442_38","name":"ad48","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*yno3GA8adiZ14mVoxpwTVw.png"},"text":"And the survey says…","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_39":{"__typename":"Paragraph","id":"c1901b16f442_39","name":"f9a2","type":"P","href":null,"layout":null,"metadata":null,"text":"You can see that we hit our 10MB goal and then some, with a download size of only 9.21MB! Compared to the 2017 app, at 60MB, we’ve managed to reduce the size by 85%! 🎉🎆","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":82,"end":88,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":161,"end":164,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*UT_XNkjswxZIyvLT2l-nyg.gif":{"__typename":"ImageMetadata","id":"1*UT_XNkjswxZIyvLT2l-nyg.gif","originalHeight":576,"originalWidth":1024,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:c1901b16f442_40":{"__typename":"Paragraph","id":"c1901b16f442_40","name":"3cb9","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*UT_XNkjswxZIyvLT2l-nyg.gif"},"text":"Actual footage from Santa HQ","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_41":{"__typename":"Paragraph","id":"c1901b16f442_41","name":"11ee","type":"H4","href":null,"layout":null,"metadata":null,"text":"Benefits for all","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_42":{"__typename":"Paragraph","id":"c1901b16f442_42","name":"2598","type":"P","href":null,"layout":null,"metadata":null,"text":"Hopefully this post has shown you that moving to App Bundles can have massive benefits for your users. Yes, it can be a non-trivial amount of work to split out all of your modules, but the benefits of that work also enforce good code practices like cohesive and decoupled modules.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_43":{"__typename":"Paragraph","id":"c1901b16f442_43","name":"b5de","type":"P","href":null,"layout":null,"metadata":null,"text":"One small caveat to the numbers above is that they also contain the results of the other size reduction techniques we used, including asset compression and moving to R8. We will discuss this more in the next blog post.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:c1901b16f442_44":{"__typename":"Paragraph","id":"c1901b16f442_44","name":"8057","type":"P","href":null,"layout":null,"metadata":null,"text":"*You might be wondering why 26 hours instead of 24? This is because the International date line is not a straight line. Kiribati has a timezone of UTC+14, which means a 26 hour time difference to Howland and Baker Islands, which use UTC-12.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":96,"end":118,"href":"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FInternational_Date_Line#\u002Fmedia\u002FFile:International_Date_Line.png","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":147,"end":153,"href":"https:\u002F\u002Fwww.timeanddate.com\u002Fworldclock\u002Fdifference.html?p1=274","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":0,"end":240,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"CollectionViewerEdge:collectionId:95b274b437c2-viewerId:lo_55aa09782afd":{"__typename":"CollectionViewerEdge","id":"collectionId:95b274b437c2-viewerId:lo_55aa09782afd","isEditor":false,"isMuting":false},"ImageMetadata:1*5pMw_nx55x_66tk77kutPQ.png":{"__typename":"ImageMetadata","id":"1*5pMw_nx55x_66tk77kutPQ.png","originalWidth":600,"originalHeight":72},"PostViewerEdge:postId:dde180716096-viewerId:lo_55aa09782afd":{"__typename":"PostViewerEdge","shouldIndexPostForExternalSearch":true,"id":"postId:dde180716096-viewerId:lo_55aa09782afd"},"Tag:android":{"__typename":"Tag","id":"android","displayTitle":"Android","normalizedTagSlug":"android"},"Tag:android-app-bundle":{"__typename":"Tag","id":"android-app-bundle","displayTitle":"Android App Bundle","normalizedTagSlug":"android-app-bundle"},"Tag:android-app-development":{"__typename":"Tag","id":"android-app-development","displayTitle":"Android App Development","normalizedTagSlug":"android-app-development"},"Post:dde180716096":{"__typename":"Post","id":"dde180716096","collection":{"__ref":"Collection:95b274b437c2"},"content({\"postMeteringOptions\":{}})":{"__typename":"PostContent","isLockedPreviewOnly":false,"bodyModel":{"__typename":"RichText","sections":[{"__typename":"Section","name":"c86f","startIndex":0,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null},{"__typename":"Section","name":"4666","startIndex":3,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null},{"__typename":"Section","name":"21eb","startIndex":44,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null}],"paragraphs":[{"__ref":"Paragraph:c1901b16f442_0"},{"__ref":"Paragraph:c1901b16f442_1"},{"__ref":"Paragraph:c1901b16f442_2"},{"__ref":"Paragraph:c1901b16f442_3"},{"__ref":"Paragraph:c1901b16f442_4"},{"__ref":"Paragraph:c1901b16f442_5"},{"__ref":"Paragraph:c1901b16f442_6"},{"__ref":"Paragraph:c1901b16f442_7"},{"__ref":"Paragraph:c1901b16f442_8"},{"__ref":"Paragraph:c1901b16f442_9"},{"__ref":"Paragraph:c1901b16f442_10"},{"__ref":"Paragraph:c1901b16f442_11"},{"__ref":"Paragraph:c1901b16f442_12"},{"__ref":"Paragraph:c1901b16f442_13"},{"__ref":"Paragraph:c1901b16f442_14"},{"__ref":"Paragraph:c1901b16f442_15"},{"__ref":"Paragraph:c1901b16f442_16"},{"__ref":"Paragraph:c1901b16f442_17"},{"__ref":"Paragraph:c1901b16f442_18"},{"__ref":"Paragraph:c1901b16f442_19"},{"__ref":"Paragraph:c1901b16f442_20"},{"__ref":"Paragraph:c1901b16f442_21"},{"__ref":"Paragraph:c1901b16f442_22"},{"__ref":"Paragraph:c1901b16f442_23"},{"__ref":"Paragraph:c1901b16f442_24"},{"__ref":"Paragraph:c1901b16f442_25"},{"__ref":"Paragraph:c1901b16f442_26"},{"__ref":"Paragraph:c1901b16f442_27"},{"__ref":"Paragraph:c1901b16f442_28"},{"__ref":"Paragraph:c1901b16f442_29"},{"__ref":"Paragraph:c1901b16f442_30"},{"__ref":"Paragraph:c1901b16f442_31"},{"__ref":"Paragraph:c1901b16f442_32"},{"__ref":"Paragraph:c1901b16f442_33"},{"__ref":"Paragraph:c1901b16f442_34"},{"__ref":"Paragraph:c1901b16f442_35"},{"__ref":"Paragraph:c1901b16f442_36"},{"__ref":"Paragraph:c1901b16f442_37"},{"__ref":"Paragraph:c1901b16f442_38"},{"__ref":"Paragraph:c1901b16f442_39"},{"__ref":"Paragraph:c1901b16f442_40"},{"__ref":"Paragraph:c1901b16f442_41"},{"__ref":"Paragraph:c1901b16f442_42"},{"__ref":"Paragraph:c1901b16f442_43"},{"__ref":"Paragraph:c1901b16f442_44"}]},"validatedShareKey":"","shareKeyCreator":null},"creator":{"__ref":"User:9303277cb6db"},"inResponseToEntityType":null,"isLocked":false,"isMarkedPaywallOnly":false,"lockedSource":"LOCKED_POST_SOURCE_NONE","mediumUrl":"https:\u002F\u002Fmedium.com\u002Fandroiddevelopers\u002Fgoogle-santa-tracker-moving-to-an-android-app-bundle-dde180716096","primaryTopic":{"__ref":"Topic:64756708407c"},"topics":[{"__typename":"Topic","slug":"android-development"},{"__typename":"Topic","slug":"programming"}],"isPublished":true,"latestPublishedVersion":"c1901b16f442","visibility":"PUBLIC","postResponses":{"__typename":"PostResponses","count":1},"clapCount":1104,"allowResponses":true,"isLimitedState":false,"title":"Google Santa Tracker — Moving to an Android App Bundle","isSeries":false,"sequence":null,"uniqueSlug":"google-santa-tracker-moving-to-an-android-app-bundle-dde180716096","socialTitle":"","socialDek":"","canonicalUrl":"","metaDescription":"","latestPublishedAt":1602778790494,"readingTime":6.782075471698113,"previewContent":{"__typename":"PreviewContent","subtitle":"This post is the first in the series which explores the improvements made to the Google Santa Tracker Android app for 2018."},"previewImage":{"__ref":"ImageMetadata:1*ksxyyNT2V-A2N626DZ9D7A.png"},"isShortform":false,"seoTitle":"","firstPublishedAt":1548784863094,"updatedAt":1638869232361,"shortformType":"SHORTFORM_TYPE_LINK","seoDescription":"","viewerEdge":{"__ref":"PostViewerEdge:postId:dde180716096-viewerId:lo_55aa09782afd"},"isSuspended":false,"license":"ALL_RIGHTS_RESERVED","tags":[{"__ref":"Tag:android"},{"__ref":"Tag:android-app-bundle"},{"__ref":"Tag:android-app-development"}],"isNewsletter":false,"statusForCollection":"APPROVED","pendingCollection":null,"detectedLanguage":"en","wordCount":1519,"layerCake":3,"responsesLocked":false}}</script><script>window.__MIDDLEWARE_STATE__={"session":{"xsrf":""},"cache":{"cacheStatus":"MISS"}}</script><script src="https://cdn-client.medium.com/lite/static/js/manifest.b2314f6d.js"></script><script src="https://cdn-client.medium.com/lite/static/js/9865.1496d74a.js"></script><script src="https://cdn-client.medium.com/lite/static/js/main.24534aeb.js"></script><script src="https://cdn-client.medium.com/lite/static/js/instrumentation.d9108df7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/reporting.ff22a7a5.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9120.5df29668.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5049.d1ead72d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4810.6318add7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6618.db187378.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2707.b0942613.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9977.5b3eb23a.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8599.1ab63137.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5250.9f9e01d2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6349.b071a958.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2648.26563adf.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8393.826a25fb.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7079.67349d50.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/3735.afb7e926.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5642.a2d9f6a1.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6546.cd03f950.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6834.08de95de.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7346.72622eb9.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2420.2a5e2d95.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/839.ca7937c2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7975.d195c6f1.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2106.21ff89d3.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7394.3d049572.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2961.00a48598.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8204.c4082863.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4391.59acaed3.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/PostPage.MainContent.c8a11795.chunk.js"></script><script>window.main();</script><script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'8e71a45b899440e2',t:'MTczMjM2OTk3MS4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10