Zoeken…


Invoering

DEX betekent uitvoerbare bytecode-bestanden van de Android-app (APK) in de vorm van Dalvik Executable (DEX) -bestanden, die de gecompileerde code bevatten die wordt gebruikt om uw app uit te voeren.

De uitvoerbare specificatie van Dalvik beperkt het totale aantal methoden waarnaar binnen een enkel DEX-bestand kan worden verwezen tot 65.536 (64 K) - inclusief Android-frameworkmethoden, bibliotheekmethoden en methoden in uw eigen code.

Om deze limiet te overwinnen, moet u uw app-buildproces configureren om meer dan één DEX-bestand te genereren, ook wel Multidex genoemd.

Opmerkingen

Wat is Dex?

Dex is de naam van het bestandsformaat en de codering waarmee Android Java-code is gecompileerd. Vroege versies van Android laadden dex binaries rechtstreeks in een virtuele machine met de naam Dalvik. Meer recente versies van Android gebruiken de Android Runtime (ART), die dex bestanden behandelt als een tussentijdse weergave en verdere compilaties daarop uitvoert voordat de toepassing wordt uitgevoerd.

Dex is een heel oud bestandsformaat, in termen van de levensduur van smartphones, en werd ontworpen voor apparaten waarvan het hoofdgeheugen werd gemeten in tientallen megabytes. De ontwerpbeperkingen van die dagen zijn tot op de dag van vandaag bij ons gebleven.

Het probleem:

De dex bestandsindeling codeert een limiet voor het aantal methoden waarnaar in één binair bestand kan worden verwezen. Omdat het deel van de bestandsindeling waarin het aantal referenties wordt opgeslagen twee bytes lang is, is het maximale aantal methodeverwijzingen 0xFFFF of 65535. Als een toepassing meer dan dat aantal methodeverwijzingen bevat, kan deze niet worden gecompileerd.

Wat eraan te doen:

Google heeft dit probleem omzeild, Multidex genoemd. Het heeft compilatie- en runtime-componenten. Zoals de naam al aangeeft, zal het tijdens het compileren code verdelen over een of meer dex bestanden. Tijdens runtime leert het de standaard ClassLoader hoe klassen uit deze bestanden kunnen worden ClassLoader .

Deze aanpak werkt goed op nieuwere apparaten, maar heeft een aantal belangrijke nadelen. Het kan de opstarttijd van de applicatie aanzienlijk verhogen en op oudere apparaten kan de Application Not Responding fouten.

Multidex, hoewel effectief, moet indien mogelijk worden vermeden.

Hoe de limiet te vermijden:

Voordat u uw app configureert om 64K of meer methodereferenties te gebruiken, moet u stappen ondernemen om het totale aantal referenties te verminderen dat wordt aangeroepen door uw app-code, inclusief methoden die zijn gedefinieerd door uw app-code of opgenomen bibliotheken. De volgende strategieën kunnen u helpen voorkomen dat u de dex-referentielimiet bereikt:

  • Controleer de directe en transitieve afhankelijkheden van uw app - Zorg ervoor dat elke grote bibliotheekafhankelijkheid die u in uw app opneemt, wordt gebruikt op een manier die zwaarder weegt dan de hoeveelheid code die aan de toepassing wordt toegevoegd. Een veel voorkomend antipatroon is het opnemen van een zeer grote bibliotheek omdat enkele bruikbare methoden nuttig waren. Door de afhankelijkheid van uw app-code te verminderen, kunt u vaak de dex-referentielimiet vermijden.
  • Verwijder ongebruikte code met ProGuard - Configureer de ProGuard-instellingen voor uw app om ProGuard uit te voeren en zorg ervoor dat krimpen is ingeschakeld voor releasebuilds. Als u krimpen inschakelt, zorgt u ervoor dat u geen ongebruikte code met uw APK's verzendt.

Het eerste punt vereist ijver en discipline van de kant van de ontwikkelaar. Bij het opnemen van externe bibliotheken moet rekening worden gehouden met de grootte van de bibliotheek. Twee populaire JSON-bibliotheken zijn bijvoorbeeld Jackson en Gson. Functioneel lijken ze redelijk op elkaar, maar Gson wordt vaker gebruikt in Android. Een reden is dat Jackson ongeveer 9.000 methoden weegt, terwijl Gson 1.900 bijdraagt.

Er zijn verschillende tools beschikbaar waarmee ontwikkelaars de grootte van hun applicatie kunnen bijhouden:

  • dexcount-gradle-plugin rapporteert het aantal methodeverwijzingen in uw APK of AAR bij elke build
  • dex-method-counts is een opdrachtregelprogramma dat het aantal methodeverwijzingen in een APK telt
  • www.methodscount.com is een webservice die de methodeverwijzingen telt in elke APK die u uploadt.

Multidex door MultiDexApplication rechtstreeks te gebruiken

Gebruik deze optie als u geen behoefte Application subklasse.

Dit is de eenvoudigste optie, maar op deze manier kunt u geen eigen Application opgeven. Als een Application nodig is, moet u hiervoor overschakelen naar een van de andere opties.

Geef voor deze optie eenvoudig de volledig gekwalificeerde klassenaam android.support.multidex.MultiDexApplication voor de android:name eigenschap van de application in de AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.myapplication">
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
</manifest>

Multidex door toepassing uit te breiden

Gebruik deze optie als uw project een Application vereist.

Geef deze Application met de eigenschap android:name in het manifestbestand in de application .

Voeg in de subklasse Application de methode attachBaseContext() toe en attachBaseContext() in die methode MultiDex.install() :

package com.example;

import android.app.Application;
import android.content.Context;

/**
 * Extended application that support multidex 
 */
public class MyApplication extends Application {

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

Zorg ervoor dat de Application is opgegeven in de application van uw AndroidManifest.xml:

<application
    android:name="com.example.MyApplication"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name">
</application>

Multidex inschakelen

Om een multidex-configuratie in te schakelen, hebt u het volgende nodig:

  • om uw Gradle-buildconfiguratie te wijzigen
  • om een MultiDexApplication te gebruiken of de MultiDex in uw Application in te schakelen

Gradle-configuratie

Voeg in app/build.gradle deze onderdelen toe:

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.1"

    defaultConfig {
        ...
        minSdkVersion 14
        targetSdkVersion 24
        ...

        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

dependencies {
  compile 'com.android.support:multidex:1.0.1'
}

Schakel MultiDex in uw applicatie in

Ga vervolgens verder met een van de drie opties:

Wanneer deze configuratie-instellingen aan een app worden toegevoegd, construeren de Android-buildhulpmiddelen een primaire dex (klassen.dex) en, indien nodig, ondersteunende (klassen2.dex, klassen3.dex).
Het buildsysteem verpakt ze vervolgens in een APK-bestand voor distributie.

Telmethode Referenties bij elke build (Dexcount Gradle Plugin)

De dexcount plug-in telt methoden en klasse resource counts na een succesvolle build.

Voeg de plug-in toe aan de app/build.gradle :

apply plugin: 'com.android.application'

buildscript {
    repositories {
        mavenCentral() // or jcenter()
    }

    dependencies {
        classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.5.5'
    }
}

Pas de plug-in toe in het app/build.gradle bestand:

apply plugin: 'com.getkeepsafe.dexcount'

Zoek naar de uitvoergegevens die door de plug-in zijn gegenereerd:

../app/build/outputs/dexcount

Vooral handig is de .html-grafiek in:

../app/build/outputs/dexcount/debugChart/index.html

Multidex door MultiDexApplication uit te breiden

Dit lijkt erg op het gebruik van een Application subklasse en het overschrijven van de methode attachBaseContext() .

Met deze methode hoeft u attachBaseContext() echter niet te overschrijven attachBaseContext() omdat dit al in de superklasse MultiDexApplication is gebeurd.

MultiDexApplication uitbreiden MultiDexApplication plaats van de Application :

package com.example;

import android.support.multidex.MultiDexApplication;
import android.content.Context;

/**
 * Extended MultiDexApplication 
 */
public class MyApplication extends MultiDexApplication {

     // No need to override attachBaseContext()

     //..........
}

Voeg deze klasse toe aan uw AndroidManifest.xml precies alsof u de toepassing zou uitbreiden:

<application
    android:name="com.example.MyApplication"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name">
</application>


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow