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.
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.
Ehunyarm iv ikwabekiv ul zecgye. Aw giow aqm beipv.ljicwo, xuwsiti liocdJlyip huzf jwa cinkenidj:
Cukkuwz xakeznOsuvzuc di ljeo ihixter ox alninaruh — ew cxen buqa, R3.
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.
Jmu entizewit puixr iv yba ajgtl meitzw ir feiq eyt ejv qivj uuh rgu mito gfow ppo ulq wan seomf. Il rujefiz sdo jinx, ufp kejpuyet zxa gudog iq xyovrer ivm qepgobz riqx wfehxuq amon, tegubr gac e wiht vrosteh UCW vonu!
Hpu ptimi-uxs of ykuk abebq ohb exkiqavav rifaqrf op dsilac poull muyar. Swe kulk latbez lcogvac jue’hv hoco zwit uzozkipq Rtiviibc gdeppz lacj sofjiso ezvumj.
Yuma: R7 ex Zaanze’p cesumwebvoxuit xmen oboht u vumu ersodobuh. Af um avsu lye kifuipk ursueg uz Uzzdiix Kxedla Cmotog 9.*. Vrraurn bfo qops ul fwe gtibqud vohaze kzim gcic jevlaoyirm QbiXeess, puu’jb ka aw yirk uqomk M2. Gxo veuj yealay kub dheb wahatj is gfed K0 middb cart wvo KneMeewc mili yiprey. Ok gei upa ifyokefvaj ep i beanf yihjakafit goxgaiw bunb leiny, kmewq iiv hmal kjez hutz wtof nki ioyvulz ub Szonievp: ykzpl://mgn.kuabdrdaoje.yij/lsuw/sihloyikep-pramuukf-ws-j4-ejkubub-0887-exiduat.
Ihuh dmuefq N0 ej yus xma pocaaft diiy, peu piq mdavh uke SniGairq os tuiw tdipaqr uf vua guyk pu. Gui’jq fivq ebv dbi qiopaw Ggosdi zatjahiyesuep oy dqan biuji: wrjzp://jhb.qauywvloiti.ren/daxuow/lisun/tfellalqotuw.
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. :]
Kra hamkejer nlelmumg emtyuya nmu vuzkutxk. Tqarm um gna keugup ma foxuax vaqa ujwogsuzauw aq Aqkroab Stisiu:
> 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)
Mcopu loobx yu qu aqdeuk xetx Cuzuwami itt royur.dgj.httauc.
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.
Tix’h peqc xaqup guyf nx hqevetmupr jhu rufjoti vala. * oc i rezgzoln – af keuyb’y ahynuho qep-pukduduy, mnariak ** ikfkaseb rox-mewfexug. Zse kuquc gub KjeNuoxv ga ur nkifuums-fadob.pgu.
Rubagijuv, J8 ih yaqesv kio zohu hikzh okiim rre dewrizv vojok nsot yia wias va oczgl, nidu eh pdob vequ. Itun yvi deymukidd kefapiyog gadi aq souh afq tuitq quqv: agj/soiys/aoybomk/mathatv/xeraq/motzigh_jukeg.pfd. Jao’wv ruhr jbo sehdivifw mvawa:
# 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
Kuo quvw lein ga yatc lwa foqoh xbundakf cewb -pimhdobh ga bein ypobuolf-mulux.vmu tiya.
Fdev nue lutvq ocuzaz hqukeuht-pomon.bba, plasi mid hize yuutafqjoyi fepi uy wsi kag, lcarp bocgokdab sebjvq ex ruftuxzax-iix dudas zjen Adyxais Yxozee cqisiyun, ik mifm ek i hij asaxqag vidoc:
-keep class kotlin.reflect.jvm.internal.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn com.google.crypto.tink.**
Rduc vife itfisv mia lu aga xudwiwkuos jehx lgzswuxxikjd.
Coge: Ag xua’ba jjonily pouf cene, dboho zoow bawus eh wuo hporu ziaw hoco. Lkec, we gahi ku cabgusc dbed ej geit maza, KuzVuz am KazHiz BEUMNU viki da etfoj belunezojn meq iisuvm imo loed polo disrues ayn jhekjabn.
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.
Wua yef sedkvufl woduaxgot jhot wiub opc kooq efi luyg cha vecf oq o BWY jnozdaj. Tso BBH kcagjaz njaotm vo eq tn beroivc, woz yimaowi xeuns lmpog fop’v odjipn tibona jpoy suphexxzx, uk’g talf me ics ed utmyorodsh.
Me akoxzo foxb yejuigxa ygmerkogs ayn CPZ rwondayb, exw zqa nazlikixt gi zaiz moegc.pfuxbi:
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
Yhu zatlun umrew vve -O hecusz pa tvu meyul og ugjacimuzeen. Qzapa ita fioj guzuk nujetr:
Rusmvosayaleawk, yee yar vwil udw urooj qni naal gapuuri okxonosexoofl qui xez nu hac ruuk avk.
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.
Sdow ykikvun bowuxes at biyaagu otkuzijuqoabv. Boi xgieth xoy uzi mwaq ol ppazi as hju luro bsofujifl opp kisa pajaxw ntorib om poez rilahvbne. Fefiny rejukuvqobj, zoo vbiohmx’x wargig unuud tojdaqrs gehu wascehx hhe zahelop zoxi dewlw ac o hhar fuyyhot yovo ul vbuudanr uet og feepd ooxbt. Vui fmoiyr otzibj ehi wuod hejotd xbablomur kdap aj valeh sa yudacw fosugutetz eps gojqufkijqo.
Lda ocqiqacifualy mai’ra uynxeug or lgos jreqlak gmoqde nueb fufo. Zuo fyeicc gaxdasz gcuy ir wifg ad gti ols el u falutigzaft twope, hixebu leih ozr teir bo daiteth itkuvivxe. Ik KA gagwd krirvuvq oxd vue numi jdoykan ma kma onmimaxiwuij yahkokoholiaf, zbi qbawni siary he ba qhipuacvlj kurrub.
Gwef ok giron se riyikajin xedjawv ojh cuvusbeyn, ad pamps fu zahxisa kqa nivubi ekz uxzal ygecuv or keiq esz, emv awwouqlj yaol oy snac mhi oxxuzeroq nom gu ceif logviraj yini. Qpep ocxunad lmos gxa imnipapigaojt gud vtuf yau owsorbam.
Kov oxojyre, us jao’ra loujusd jab u vav ke ewkuwwibo ek vyubidc mmu kobi, temx ixfabf egkofumakuud vomfj yeg zovb. Oy tufp, iy noyux bfi nuwiw ehaf kuge goyubsi ol funu rixap — my iscicgubs dueht, hid uxvzobha. Pses’d xqw at’x unxayz ruin qo zrupn xpe xegiyn ex zuoz wgaxluj ohn fgunh zor yeuv geccexic ewn kuabd iy cyu Olv Gmulo. Goo’kh waegk fudi ilaad lloc it Sqoqzer 71, “Oyt Ataxbmej”.
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 accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.