Recherche…


Introduction

DEX désigne les fichiers de code-octet exécutables de l'application Android (APK) sous la forme de fichiers Dalvik Executable (DEX), qui contiennent le code compilé utilisé pour exécuter votre application.

La spécification Dalvik Executable limite le nombre total de méthodes pouvant être référencées dans un seul fichier DEX à 65 536 (64 Ko), y compris les méthodes d'infrastructure Android, les méthodes de bibliothèque et les méthodes de votre propre code.

Pour surmonter cette limite, vous devez configurer le processus de génération de votre application afin de générer plusieurs fichiers DEX, appelés Multidex.

Remarques

Qu'est ce que le dex?

Dex est le nom du format de fichier et du codage auquel le code Java Android est compilé. Les premières versions d'Android chargeraient et exécuteraient des binaires dex directement dans une machine virtuelle nommée Dalvik. Les versions plus récentes d'Android utilisent Android Runtime (ART), qui traite les fichiers dex comme une représentation intermédiaire et effectue de nouvelles compilations avant d'exécuter l'application.

Dex est un format de fichier très ancien, en termes de durée de vie des smartphones, conçu pour les périphériques dont la mémoire principale était mesurée en dizaines de mégaoctets. Les limites de conception de ces jours sont restées avec nous à ce jour.

Le problème:

Le format de fichier dex encode une limite au nombre de méthodes pouvant être référencées dans un seul fichier binaire. Étant donné que la partie du format de fichier qui stocke le nombre de références comporte deux octets, le nombre maximal de références de méthode est 0xFFFF ou 65535. Si une application contient plus de ce nombre de références de méthode, la compilation échouera.

Que faire à ce sujet:

Google a fourni un moyen de contourner ce problème, appelé Multidex. Il comporte des composants à la compilation et à l'exécution. Comme son nom l'indique, au moment de la compilation, il divisera le code entre un ou plusieurs fichiers dex . Lors de l'exécution, le ClassLoader par défaut ClassLoader à rechercher les classes à partir de ces fichiers.

Cette approche fonctionne bien sur les nouveaux périphériques, mais présente des inconvénients importants. Il peut augmenter le temps de démarrage de l' application de façon spectaculaire, et sur les appareils plus anciens peuvent causer Application Not Responding des échecs.

Multidex, bien qu'efficace, devrait être évité si possible.

Comment éviter la limite:

Avant de configurer votre application pour permettre l'utilisation de références de méthode 64 Ko ou plus, vous devez prendre des mesures pour réduire le nombre total de références appelées par votre code d'application, y compris les méthodes définies par votre code d'application ou les bibliothèques incluses. Les stratégies suivantes peuvent vous aider à éviter d’atteindre la limite de référence dex:

  • Examinez les dépendances directes et transitives de votre application - Assurez-vous que toute dépendance de bibliothèque importante que vous incluez dans votre application est utilisée d'une manière qui dépasse la quantité de code ajoutée à l'application. Un anti-pattern commun est d'inclure une très grande bibliothèque car quelques méthodes utilitaires étaient utiles. La réduction des dépendances du code de votre application peut souvent vous aider à éviter la limite de référence dex.
  • Supprimez le code inutilisé avec ProGuard - Configurez les paramètres ProGuard pour que votre application exécute ProGuard et assurez-vous que la réduction des créations est activée. L'activation du rétrécissement garantit que vous ne livrez pas de code inutilisé avec vos APK.

Le premier point nécessite une diligence et une discipline de la part du développeur. Lors de l'intégration de bibliothèques tierces, il faut tenir compte de la taille de la bibliothèque. Par exemple, deux bibliothèques JSON populaires sont Jackson et Gson. Fonctionnellement, ils sont assez similaires, mais Gson a tendance à voir une plus grande utilisation dans Android. L’une des raisons est que Jackson pèse environ 9 000 méthodes, alors que Gson en contribue 1 900.

Plusieurs outils sont disponibles pour aider les développeurs à suivre la taille de leur application:

  • dexcount-gradle-plugin indique le nombre de références de méthode dans votre APK ou AAR sur chaque version
  • dex-method-count est un outil en ligne de commande qui compte le nombre de références de méthode dans un APK
  • www.methodscount.com est un service Web qui comptera les références de méthode dans tout fichier APK que vous téléchargez.

Multidex en utilisant MultiDexApplication directement

Utilisez cette option si vous n'avez pas besoin d'une sous-classe d' Application .

C'est l'option la plus simple, mais de cette façon, vous ne pouvez pas fournir votre propre sous-classe d' Application . Si une sous-classe d' Application est nécessaire, vous devrez passer à l'une des autres options pour le faire.

Pour cette option, spécifiez simplement le nom de classe complet android.support.multidex.MultiDexApplication pour la propriété android:name de la balise d' application dans le fichier 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 en étendant l'application

Utilisez cette option si votre projet nécessite une sous-classe Application .

Spécifiez cette sous-classe d' Application à l'aide de la propriété android:name dans le fichier manifeste de la balise d' application .

Dans la sous-classe Application , ajoutez la méthode attachBaseContext() et, dans cette méthode, appelez 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);
    }
}

Assurez-vous que la sous-classe Application est spécifiée dans la balise d' application de votre AndroidManifest.xml:

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

Activation de Multidex

Pour activer une configuration multidex, vous avez besoin:

  • changer votre configuration de build Gradle
  • utiliser MultiDexApplication ou activer MultiDex dans votre classe Application

Configuration de Gradle

Dans app/build.gradle ajoutez ces parties:

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

Activer MultiDex dans votre application

Ensuite, effectuez l'une des trois options suivantes:

Lorsque ces paramètres de configuration sont ajoutés à une application, les outils de génération Android construisent un dex (classes.dex) principal et prennent en charge (classes2.dex, classes3.dex) selon les besoins.
Le système de compilation les intégrera ensuite dans un fichier APK pour la distribution.

Méthode de comptage Références sur chaque version (Dexcount Gradle Plugin)

Le plug-in dexcount compte les méthodes et le nombre de ressources de classe après une génération réussie.

Ajoutez le plugin dans l' app/build.gradle :

apply plugin: 'com.android.application'

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

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

Appliquez le plugin dans le fichier app/build.gradle :

apply plugin: 'com.getkeepsafe.dexcount'

Recherchez les données de sortie générées par le plug-in dans:

../app/build/outputs/dexcount

Le graphique .html est particulièrement utile dans:

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

Multidex en étendant MultiDexApplication

Cela ressemble beaucoup à l'utilisation d'une sous-classe Application et au attachBaseContext() méthode attachBaseContext() .

Cependant, en utilisant cette méthode, vous n'avez pas besoin de remplacer attachBaseContext() car cela est déjà fait dans la super-classe MultiDexApplication .

Étendez MultiDexApplication au lieu 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()

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

Ajoutez cette classe à votre AndroidManifest.xml exactement comme si vous étendiez l'application:

<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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow