2013-03-15 17 views
27

La mia squadra e io abbiamo ereditato un grande progetto Android da un'altra squadra. Si dice che l'intera applicazione con tutte le librerie incluse abbia circa 35000 metodi. Ora abbiamo il compito di implementare un nuovo servizio nell'app in cui è necessario utilizzare i buffer del protocollo.Come risolvere il problema con la limitazione del compilatore Dalvik sui metodi 64K?

Il problema è che il file .jar generato con tutti i file .proto richiesti crea un altro paio di 35000 metodi, ovvero 70000 metodi. E se non sei a conoscenza, il compilatore Android ha una limitazione di 65536 metodi per file .dex. Siamo chiaramente oltre quel limite e stiamo ottenendo il seguente errore cercare di compilare l'applicazione:

Unable to execute dex: method ID not in [0, 0xffff]: 65536 
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536 

Sì, l'architettura applicativa dovrebbe probabilmente essere ristrutturati, ma ci vorrà del tempo. E per ora stiamo cercando di capire una soluzione per aggirare questo problema temporaneamente.

Qualche suggerimento?

+0

Se la vostra l'app contiene molti metodi (e non è possibile sbarazzarsi di alcuni di essi) la soluzione probabilmente dovrà suddividere l'app in parti più piccole che possono essere costruite in file dex separati. Vedi [questo blogpost] (http://android-developers.blogspot.se/2011/07/custom-class-loading-in-dalvik.html) per un esempio di come farlo. – Michael

+0

Il team di Facebook ha appena pubblicato un messaggio relativo a questo problema esatto, l'altro giorno. https://www.facebook.com/notes/facebook-engineering/under-the-hood-dalvik-patch-for-facebook-for-android/10151345597798920 – Rawkode

+2

@Rawkode: il problema di Facebook era dovuto a un sottotono "LinearAlloc" buffer nelle versioni precedenti di Android (froyo, gingerbread). Il limite di riferimento del metodo 64K è riportato nelle istruzioni di Dalvik. – fadden

risposta

12

È possibile utilizzare un altro file DEX. Ecco come si fa:

http://android-developers.blogspot.co.il/2011/07/custom-class-loading-in-dalvik.html

+4

Ecco uno script per contare il numero di metodi in ogni jar: https: //gist.github. it/toms972/c83504df2da1176a248a –

+1

Il post collegato è un po 'obsoleto, mostra come caricare più file DEX in un progetto basato su Ant. Inoltre, usa direttamente DexClassLoader, una cosa che non è più necessaria dal momento che android.support.multidex ti aiuta in questo ed è disponibile nella libreria di supporto (revisione 21). La spiegazione dettagliata su come integrare MultiDex nella tua app è qui: https://www.contentful.com/blog/2014/10/30/android-and-the-dex-64k-methods-limit/ – woot

+0

simile a @TomSusel script, abbiamo scritto un piccolo plugin gradle che ti dà una visione più approfondita del tuo conteggio dei metodi e da dove proviene su ogni build: https://github.com/KeepSafe/dexcount-gradle-plugin – philipp

7

Abilitare Proguard (http://developer.android.com/tools/help/proguard.html) per rimuovere i metodi non utilizzati. Il generatore di protobuf crea migliaia di metodi che non vengono mai effettivamente utilizzati.

I micro-protobuffer (https://code.google.com/p/micro-protobuf/) possono anche essere utili.

+1

Ho iniziato a utilizzare proguard per questo ma non sono sicuro di come abilitarlo per le build di configurazione di debug/run all'interno di Eclipse. Qualche suggerimento su questo? –

+0

Ci sono alcuni post su StackOverflow che possono essere utili, come http://stackoverflow.com/questions/4732656/enabling-proguard-in-eclipse-for-android. – fadden

+4

Non riesco a trovare nulla su quella domanda che menziona usando proguard con le configurazioni di debug/run con Eclipse ... –

1

Se questo è il primo uso di buffer protocollo, si poteva guardare JavaME alternativa implementazioni cioè

ci sono altri elencati in Third party add ons. Se non ne hai mai usato nessuno, sembrano essere più piccoli e non hanno tutti i metodi creati dai buffer del protocollo standard.

1

Abbiamo recentemente aggiunto Nano Protobufs ad Android che riduce significativamente il numero di metodi generati.

+0

Ulteriori dettagli, per favore, se volere? – icedwater

+0

Sì, per favore ... Maggiori dettagli su cosa esattamente dobbiamo fare per iniziare a utilizzare Nano Protobufs ... –

4

Square ha riscontrato problemi simili e ha creato Wire per gestire l'esplosione del metodo causata da protobufs. Sostengono di aver ucciso 10.000 metodi.

4

Nelle versioni dei servizi di Google Play precedenti alla 6.5, dovevi compilare l'intero pacchetto di API nella tua app. In alcuni casi, fare ciò ha reso più difficile mantenere il numero di metodi nella tua app (comprese le API di framework, i metodi di libreria e il tuo codice) sotto il limite di 65.536.

Dalla versione 6.5, puoi invece compilare in modo selettivo le API del servizio di Google Play nella tua app. Ad esempio, per includere solo le API Google Fit e Android Wear, sostituisci la seguente riga nella tua build.File Gradle:

compile 'com.google.android.gms:play-services:6.5.87' 

con queste righe:

compile 'com.google.android.gms:play-services-fitness:6.5.87' 
compile 'com.google.android.gms:play-services-wearable:6.5.87' 

per più di riferimento, è possibile fare clic here

0

Se si utilizza Eclipse Questa è la più semplice lavoro intorno Click Here!