Sök…


Introduktion

DEX betyder Android-appens (APK) körbara bytekodfiler i form av Dalvik Executable (DEX) -filer, som innehåller den sammanställda koden som används för att köra din app.

Den exekverbara Dalvik-specifikationen begränsar det totala antalet metoder som kan hänvisas till i en enda DEX-fil till 65 536 (64K) - inklusive Android-rammetoder, biblioteksmetoder och metoder i din egen kod.

För att övervinna denna gräns krävs att du konfigurerar appen för att generera mer än en DEX-fil, känd som en Multidex.

Anmärkningar

Vad är dex?

Dex är namnet på filformatet och kodningen till vilken Android Java-kod är kompilerad. Tidigare versioner av Android skulle ladda och köra dex binärer direkt i en virtuell maskin med namnet Dalvik. Nyare versioner av Android använder Android Runtime (ART), som behandlar dex filer som en mellanliggande representation och utför ytterligare sammanställningar på den innan applikationen körs.

Dex är ett mycket gammalt filformat, vad gäller smarttelefonens livslängd, och designades för enheter vars huvudminne uppmättes i tiotals megabyte. Dessa dags designbegränsningar har förblivit hos oss till denna dag.

Problemet:

dex filformatet kodar en gräns för antalet metoder som kan hänvisas till i en enda binär. Eftersom den del av filformatet som lagrar antalet referenser är två byte långt är det maximala antalet 0xFFFF , eller 65535. Om en applikation innehåller mer än det antalet metodreferenser kommer den inte att kompilera.

Vad du ska göra åt det:

Google har gett en väg runt detta problem, kallad Multidex. Den har kompileringstider och körtidskomponenter. Som namnet antyder kommer den vid kompileringstiden att dela kod mellan en eller flera dex filer. Vid körning kommer det att lära standard ClassLoader hur man letar upp klasser från dessa filer.

Denna metod fungerar bra på nyare enheter, men har några väsentliga nackdelar. Det kan öka applikationens starttid dramatiskt och på äldre enheter kan orsaka fel på Application Not Responding .

Multidex, även om det är effektivt, bör undvikas om möjligt.

Hur man undviker gränsen:

Innan du konfigurerar din app för att möjliggöra användning av 64K eller fler metodreferenser, bör du vidta åtgärder för att minska det totala antalet referenser som anropas av din appkod, inklusive metoder som definieras av din appkod eller bibliotek som ingår. Följande strategier kan hjälpa dig att undvika att träffa dex-referensgränsen:

  • Granska appens direkta och transitiva beroenden - Se till att allt stort bibliotekberoende du inkluderar i din app används på ett sätt som överstiger mängden kod som läggs till applikationen. Ett vanligt antimönster är att inkludera ett mycket stort bibliotek eftersom några få verktygsmetoder var användbara. Att minska beroende av appkod kan ofta hjälpa dig att undvika dex-referensgränsen.
  • Ta bort oanvänd kod med ProGuard - Konfigurera ProGuard-inställningarna för att din app ska köra ProGuard och se till att du har krympat aktiverat för release-builds. Aktivering av krympning säkerställer att du inte levererar oanvänd kod med dina APK: er.

Den första punkten kräver noggrannhet och disciplin från utvecklarens sida. När man integrerar bibliotek från tredje part måste man beakta bibliotekets storlek. Två populära JSON-bibliotek är till exempel Jackson och Gson. Funktionellt sett är de ganska lika, men Gson brukar se större användning i Android. En anledning är att Jackson väger cirka 9 000 metoder, medan Gson bidrar med 1 900.

Det finns flera verktyg som hjälper utvecklare att hålla reda på storleken på sin applikation:

Multidex genom att använda MultiDexApplication direkt

Använd det här alternativet om du inte behöver en underklass för Application .

Detta är det enklaste alternativet, men på det här sättet kan du inte ange din egen Application . Om en underklass för Application behövs måste du byta till ett av de andra alternativen för att göra det.

För det här alternativet anger du helt enkelt klassens android.support.multidex.MultiDexApplication för android.support.multidex.MultiDexApplication android:name för application i 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 genom att utöka applikationen

Använd det här alternativet om ditt projekt kräver en underklass för Application .

Ange denna underklass för Application med egenskapen android:name i manifestfilen i application .

I underklassen för Application lägger attachBaseContext() metoden attachBaseContext() åsidosättande och kallar MultiDex.install() i den metoden:

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);
    }
}

Se till att underklassen för Application anges i application i din AndroidManifest.xml:

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

Aktivera Multidex

För att aktivera en multidex-konfiguration behöver du:

  • för att ändra din Gradle build-konfiguration
  • att använda en MultiDexApplication eller aktivera MultiDex i din Application

Gradle konfiguration

app/build.gradle till dessa delar i app/build.gradle :

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'
}

Aktivera MultiDex i din applikation

Fortsätt sedan med ett av tre alternativ:

När dessa konfigurationsinställningar läggs till i en app konstruerar Android build-verktygen en primär dex (klasser.dex) och stöder (klasser2.dex, klasser3.dex) efter behov.
Byggsystemet kommer sedan att paketera dem i en APK-fil för distribution.

Räknemetodreferenser för varje byggnad (Dexcount Gradle Plugin)

Dexcount-plugin räknar metoder och klassresursantal efter en framgångsrik byggnad.

Lägg till plugin i app/build.gradle :

apply plugin: 'com.android.application'

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

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

Använd plugin i app/build.gradle filen:

apply plugin: 'com.getkeepsafe.dexcount'

Leta efter utgångsdata som genereras av plugin-programmet:

../app/build/outputs/dexcount

Speciellt användbart är .html-diagrammet i:

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

Multidex genom att utöka MultiDexApplication

Detta liknar mycket att använda en underklass för Application och åsidosätta attachBaseContext() .

Men med den här metoden behöver du inte åsidosätta attachBaseContext() eftersom det redan är gjort i MultiDexApplication superklass.

MultiDexApplication istället för 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()

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

Lägg till den här klassen till din AndroidManifest.xml precis som om du utvidgar applikationen:

<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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow