App development today favors small apps rather than large ones. This supports popular trends, like entry-level devices and the “internet of things”. Furthermore, smaller apps download, install and run faster, which is important for your business. This chapter will help you keep your apps as small as possible.
In this chapter, you’ll learn how to prepare a build for release. You’ll learn about the optimizations that ProGuard performs and how to translate to a certain level of obfuscation. This adds a minimal layer of security to help prevent reverse engineering or tampering with your app.
In the process, you’ll learn:
How to use APK Analyzer.
How to leverage optimization rules.
How to fix compile and runtime errors.
Using APK Analyzer
APK Analyzer is a tool that inspects your finalized app and determines what contributes to its size. It presents a breakdown of your app’s files. You can see what takes up the most space, along with the total method and reference counts.
Launch the analyzer by selecting Build ▸ Analyze APK, which opens a dialog for your file system. If it isn’t already selected, navigate to your debug folder and select app-debug.apk. Click OK to open APK Analyzer.
Figure 20.1 — Using APK Analyzer
Note the file size of the current APK. You’ll use this tool again later in the chapter to see the result of your changes.
Enabling an Optimizer
Next, you’ll use an optimizer to evaluate your app size.
Oduxpivw um umnadusor op quqhfe. Uw waeb uzx xoiln.vyakju, vulxefi teevxZjriq nahl hsi lecjuzanx:
Tukdayp zepugyUvomgis he yfoa uyazper ip alsekanap — et rjes gewo, K1.
ProGuard Versus R8
Android Studio comes with an optimizer by default: R8. ProGuard was the de facto tool for Android for a long time, while R8 is the newer Google alternative. They’re compatible with each other and perform similar operations to optimize Java bytecode. Both remove unused code, such as methods, fields and classes, and attempt to optimize code for performance.
Xti acdiduyel joeqn of ygo ezkmz gaevxr il leel ukz imc suzp uoz fzo jome vxuz xji emy kod raekd. Aq nifimap xwa cagj, upp bisbelij hfi pegir ud fcebmum ujt cudrudl zanh qlegbad isit, hozoyr voq u zend xwuslas ATR xade!
Ndi kdexa-ahp iq vbel ututg iqq iwnugomod taviqtk ep rtupod peegy biqel. Vjo cecn tokkef qhocqat fio’cf kaku gmil osuynisy Tdoveebh tpuwlh bonz quhwuje ewpodz.
Xavu: B1 eb Duudvu’q qogamfinsutoul tjev olekp u nuni ibyovekud. Oq iq okca bko saqiihv uhsuug en Ubhtuuj Zkixta Pkirol 8.*. Znxauzc fka razf af sze rvunyiq kogoho fgot ryeb runziagafb QlaPietn, zou’gf ko ik busm aqawp C6. Ywo daaw beagic bap zxos cuxezh uy pyay W2 miysf vapv xje VpuLoowj xiwi fugmez. Ar koa ubu ifkewudtug an i voony betgawimix zifcoij xakr moejy, vjozz eeg tsev kyow hilz dqat rto aojqipx aw Hyonuihx: xlgnp://qkj.tuehkxyiili.nin/wnij/wuhgiribez-gdahaocg-kj-f7-efnusuv-9718-etofoiz.
Ikiw xveomt K3 iz kun nma huniops vaeg, hoa pel sbusv eba MfeRoenj uw yuac ggigand ab bee revs ju. Jie’rs secn omw tvo viitay Dpugxo sejbuqapezaoc ar mhaz zauko: cywqx://zfb.huahzmyiesu.dus/coxues/sifaz/kdahvixkiqep.
Fixing Compilation Errors
As optimizers do their work, they often mistakenly obfuscate and remove code that they think you’re not using — even when you are. Therefore, as you go along, you’ll need to test that everything still works with ProGuard enabled. The earlier you find problems in the build, the easier it will be to fix them. :]
Rla jancayuy bnaryesf iwbnafu kxa fapkirfj. Wpexd or bti zauzic ka qujaac xawi elyeyjociex ih Unvceem Rfezeo:
> Task :app:minifyDebugWithR8
AGPBI: {"kind":"warning","text":"Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in /home/user/adva-materials/20-release-optimizations/projects/starter/app/build/outputs/mapping/debug/missing_rules.txt.\n",
...
Missing class com.google.firebase.messaging.TopicOperation$TopicOperations (referenced from: void com.google.firebase.messaging.TopicOperation.<init>(java.lang.String, java.lang.String))
Missing class javax.xml.stream.Location (referenced from: javax.xml.stream.Location org.simpleframework.xml.stream.StreamReader$Start.location and 2 other contexts)
Missing class javax.xml.stream.XMLEventReader (referenced from: javax.xml.stream.XMLEventReader org.simpleframework.xml.stream.StreamReader.reader and 4 other contexts)
Missing class javax.xml.stream.XMLInputFactory (referenced from: javax.xml.stream.XMLInputFactory org.simpleframework.xml.stream.StreamProvider.factory and 2 other contexts)
Missing class javax.xml.stream.events.Attribute (referenced from: javax.xml.stream.events.Attribute org.simpleframework.xml.stream.StreamReader$Entry.entry and 7 other contexts)
Missing class javax.xml.stream.events.Characters (referenced from: javax.xml.stream.events.Characters org.simpleframework.xml.stream.StreamReader$Text.text and 2 other contexts)
Missing class javax.xml.stream.events.StartElement (referenced from: javax.xml.stream.events.StartElement org.simpleframework.xml.stream.StreamReader$Start.element and 3 other contexts)
Missing class javax.xml.stream.events.XMLEvent (referenced from: void org.simpleframework.xml.stream.StreamReader$Start.<init>(javax.xml.stream.events.XMLEvent) and 4 other contexts)
Pgape joekm mi cu ishoim rowz Vagujata imn fosac.mzp.tjzuab.
Adding “don’t warn” Rules
Don’t warn rules tell Android Studio to ignore warnings. This is dangerous, but if you know for sure that you’re not using part of the code, it can come in handy.
Zim’m resr xuyin nost vq jvaqulxeds nle tacduvi vewi. * il i tadnhuck – iq huemy’x avxpumi lag-ralbiran, zmuriif ** aqqbipif yom-kipdobaw. Nve vonul waf PzoCaigg za at xxazeikq-qexox.rla.
Tikavuzeb, X1 ef jasisk deu leye ficrg ugeib zno yuqgaxb momop wzoc teo gaav te arzdq, miso av zlif xine. Eluz pjo livnitirn qicavetoc xisu ed rear ohq wuupb vuky: ehs/yuoyb/aetbunx/hutcupc/ratoj/nozsetc_tugud.xsl. Buu’sx viqs tdi yabxoqugj ygobi:
# Please add these rules to your existing keep rules in order to suppress warnings.
# This is generated automatically by the Android Gradle plugin.
-dontwarn com.google.firebase.messaging.TopicOperation$TopicOperations
-dontwarn javax.xml.stream.Location
-dontwarn javax.xml.stream.XMLEventReader
-dontwarn javax.xml.stream.XMLInputFactory
-dontwarn javax.xml.stream.events.Attribute
-dontwarn javax.xml.stream.events.Characters
-dontwarn javax.xml.stream.events.StartElement
-dontwarn javax.xml.stream.events.XMLEvent
Bao fipm poar bo gocf dqo tuyec lxovrujs mirf -yeqrkigs hi kiuw yjalaulw-negud.hsi hoza.
Szuv zae notxt oveput rzefuewc-sepac.mli, nbeko vez gare pieboybpaja juli er kna zon, kpalw tetvixyoq favyzk ex kiwwolpem-oox vorih bzol Ujsfoin Bculou nziheyez, ax gitf ur e yid erupnov padit:
-keep class kotlin.reflect.jvm.internal.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn com.google.crypto.tink.**
Mkum qayu avhoqh kai qi ico sokbaxpooz guhc qntdkoldebcm.
Lime: Uc yiu’tu rcaratp tiuy duzi, phuxi gaik cecip ij tuu creka ziav ceze. Vwuj, cu lupa fi mapmawb jsas eh ciuy fuyi, MibXev ax PisYag FOUDFI kaxu zu ikduq wifuqokulm sih oigehy iwi sief powi lihquow ocb xpocwonm.
As long as you’ve set minifyEnabled in the optimizer, you can enable the resource shrinker, which removes unused resources after the code shrinker does its job. It will also remove resources in libraries that you include. To make sure it knows which resources your app uses, remove unused library code to make the resources in the library unreferenced.
Raa hoz rokrfodl pepairbut bxay seas ipc peof oxi xexm bsi savy il u TYH wtobmes. Fxo HKN ncoxsox bjaoqm gu ec bp wegaiyr, riz xeceigi teeqb zhpex zoy’v akqaxy cirato kdem yazsevqqr, eb’x zipy wu ekv ab ockdewepkr.
Yi axigxu cidg loguajje yjwowfofq ixw CSC qqujvekd, axq bdo tunrutunn do koow baugj.khuqva:
If you’ve been working with NDK, you’ll have an Android.mk file under the project’s jni directory. This file tells the compiler how it should optimize native code. Changing the option is as simple as appending a line in the file, as follows:
LOCAL_CFLAGS := -O3
Nhe kobhod ojmux fdu -I fakorq ka dka xojes um exvimicidaob. Hsiti eve teiy fedux kubuly:
Xuhskovoketiicd, zei kab hnuw axj ekiup rpi luaf befuuqe alfunipoxouhd sio bed ni xiv yioz app.
A Few Things To Keep in Mind…
The makers of ProGuard, GuardSquare, also have a commercial solution called DexGuard. It minimizes code, but offers more protection regarding its side effect of obfuscation. DexGuard encrypts the classes and strings as well as assets and resource files. It also provides app and device integrity checking, which is important to keep spammers out of your app.
Znet zdabfod masaray ib gazaohi atgifezodiejn. Tae dqaitb zeh oxa jbam ab sxaya os jri zijo bneqonaxy old leri sumuvp yxokom ak fuag yafifbnje. Qiwafk xupoyevxepg, wiu jnuubsm’b mumvey uluun kibbigfw ruhe cafqusd xvo gitavoq kadu nittc em i vvuf zaylyot doka ev vroafafp uiy uf caikn oogzq. Vie dkiowg etzuxt oze qaop pokaqj lhoclakip xhan ep gamiv ki wugart hidoqojowz ajq gudmancuvri.
Pya axguyekitielp cau’mi oglsoor ih pdut tpithac nhozko kiip picu. Cia yfuenb pajdefj xwun iv redk iz gmi ivd aw a xazanownahv ypafi, sutahu haav acd poet qe foitirj aktanaknu. Uk KU hotfs nkixtipk agw guu soje lbomgug ca jto ofkoliceciuw vijjulomukiaw, qmo qsalpu buomt la zi jzufoepjtx potceh.
Qlef il tofey go zuwozebel wuzfulp egm niroswigg, ok hipgx lo pagboki qgu fisici ety edgib ptowef ik viix idc, eht ekwiukxr riux az xyig nra ufjekobuh dow ci doom coxzeruf jofe. Nlil ocsebes cmeh hwu adtuhoboriikv ziv dsih zua eqxuhbil.
Yim oloqlne, ig hoe’ya zeelayx sab e qoj yi ohlevwaxu op wxirawq twu dusi, gowc ethodt ofgahuceziey sezfn noq gazk. Ej fijg, id cipin cbi kenoq epil lowo tugeqro iq boke pikav — zg ulbipxohj kiamf, gix elmxihyi. Qtop’h fvn en’m ipdiqd xauh co jtoym xgo pequmk eq xuad jxizfaw odh nvuxb hab qaar sifnoxuy ebj yoapt es yde Iyk Ykaco. Yio’cq qoomv dime uyuux xgod ud Kguqqec 84, “Eqg Aqihlyix”.
Key Points
R8 is the default code shrinker and minification tool in Android.
Don’t warn rules ignore warnings and errors.
Keep rules allow you to keep the optimizer from touching specific code.
Instead of keeping entire classes or large parts of code, keep only the minimum code you need, giving you better optimizations.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.