Conteggio dei metodi di riferimento aumentato dopo la modularizzazione dell'app


16

AS: 3.5.3; Plugin Android Gradle: 3.5.0; Grado: 5.6.2;

Abbiamo osservato un drastico aumento del numero di metodi a cui fa riferimento la nostra app dopo aver suddiviso il modulo "app" in diversi piccoli moduli. Ma la cosa strana è che l'aggiunta di metodi di riferimento per ogni classe è inferiore al totale citato in Android Apk Analyzer Tool.

A scopo di test, ho spostato WebActivity.class dal modulo "app" al modulo "adattatori" e il conteggio dei metodi di riferimento è aumentato di 181 metodi.

Riassumere:

app / WebActivity = 63546 Metodi di riferimento effettivi ma che mostrano 65394 metodi. adapter / WebActivity = 63543 Metodi di riferimento effettivi ma con 65575 metodi.

Abbiamo osservato che il "conteggio dei metodi di riferimento" è aumentato di quasi 10k dopo aver aggiunto / suddiviso 4 nuovi moduli.

Qual è il problema esatto?

In che modo la modularizzazione delle app può aumentare drasticamente il conteggio dei metodi di riferimento così elevato?

Di seguito sono riportati gli screenshot che ho preso di due differenze APK solo differenza è WebActivity spostato dal modulo 'app' al modulo 'adattatore' e 181 metodi di riferimento aumentati:

WebActivity nel modulo 'app' inserisci qui la descrizione dell'immagine

Spostato WebActivity nel modulo 'adattatore' inserisci qui la descrizione dell'immagine

Negli screenshot, perché l'aggiunta di metodi di riferimento per ciascuna classe (contrassegnata in rosso) non è uguale al totale fornito in Apk Analyzer?


Ho creato un problema, puoi seguirlo
Rohit Surwase

Risposte:


9

Ho letto per molto tempo le prestazioni del codice e l'ottimizzazione dei parametri. Tuttavia, i programmi Android sono uno dei miei obiettivi.

Iniziamo intro i concetti di base o più importanti in cui ci aiutano a raggiungere una soluzione.

Come ha affermato lo sviluppatore Android

il modulo può essere costruito, testato e sottoposto a debug in modo indipendente

Pertanto, i moduli hanno il loro grado e dipendenze e puoi esplorarlo nel progetto Hierarchy Viewer.

È un dato di fatto, l' accento sulla modularizzazione in materia di manutenzione . A differenza delle problematiche legate alle prestazioni, perché la modularizzazione ha questo importante impatto:

  • Aumenta la profondità dell'eredità

Ecco un diagramma che l'ho disegnato per chiarirlo. Come puoi vedere mentre usi il modulo discreto, per invocare il Metodo A viene 2N micro secsconfrontato con il N micro secsmodulo senza discreto.

inserisci qui la descrizione dell'immagine

Questa domanda mi viene in mente che i metodi di riferimento contano ciò che riguarda la profondità dell'eredità?

La risposta è: sebbene l'uso della modularizzazione aumenti i metodi di riferimento, ma in realtà non influisce sulle prestazioni dell'app e il principale problema possibile è la profondità dell'eredità in cui nella maggior parte dei casi è ignorabile .

Sottolineo che un aumento dei metodi di riferimento nella modularizzazione è dovuto a ciascun modulo e dipendenze del modulo

In che modo la modularizzazione delle app può aumentare drasticamente il conteggio dei metodi di riferimento così elevato?

Condizioni in cui l'analizzatore APK ha un impatto importante sui metodi di riferimento

Si noti inoltre che la riduzione e la riduzione del codice possono anche modificare considerevolmente il contenuto di un file DEX dopo la compilazione del codice sorgente.

Oltre alla precedente dichiarazione ufficiale, voglio aggiungere un'altra condizione in cui l'analizzatore APK ad impatto sia:

quanto ha vissuto lo sviluppatore nella modularizzazione?

la modularizzazione è come una casa che l' architettura (sviluppatore) definisce dove dovrebbe essere la cucina e dove dovrebbe essere la stanza di riposo e dove dovrebbe essere il WC. E se l'architettura decidesse di combinare WC e cucina? Sì, questo è un disastro.

Ciò può accadere durante la modularizzazione se lo sviluppatore non ha molta esperienza.


Risposta a domande OP in aggiunta a informazioni aggiuntive

Qui rispondo alle domande poste nei commenti

Perché il Gradle separato dovrebbe essere aggiunto al conteggio del metodo di riferimento? E per una dipendenza separata, se il risultato finale è un singolo APK, non penso che dipendenze duplicate in 'app' e il modulo funzione si aggiungerebbero al conteggio dei metodi di riferimento.

Poiché i moduli possono essere costruiti, testati e sottoposti a debug, DEVONO avere il proprio Grado e dipendenze.

Mentre viene rispettato il progetto multi-modulo, il compilatore genera diversi .dexfile tra cui:

  • un .dexfile per le dipendenze totalmente integrate
  • moduli .dexs

il .dexfile delle dipendenze è un'integrazione di tutti i gradi dei moduli

Diamo un'occhiata a come un livello di modulo influisce sul conteggio finale dei Mothods referenziati ?!

ci sono 2 APK secondi con lo stesso risultato ma differenza nei conteggi dei metodi di riferimento.

Figura 1 figura 2

Sono entrambe attività vuote che hanno una 1.7kdifferenza nel conteggio dei metodi di riferimento che dipende molto dalla loro funzionalità. Loro differenza chiave è sul Gradle del loro modulo a cui uno è stato configurato

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}

Un altro configurato per

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.2.0-alpha01'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
}

Sebbene siano solo attività vuote, ma una minima differenza in Grado ha causato la 1.7kdifferenza nei conteggi dei metodi di riferimento.

E App Gradle lo è

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation project(path: ':module')
}

la principale preoccupazione è perché l'aggiunta del conteggio dei metodi a riferimento individuale è diversa dal conteggio totale dei metodi a cui fa riferimento Apk Analyzer?

Questo è solo il filtro IDE nient'altro. di sicuro, se si seleziona solo un .dexfile Il conteggio dei metodi di riferimento è uguale al SUM di ogni riga Conteggi del metodo di riferimento ma se si selezionano più .dexfile, si vedrà la differenza nel SUM e nel conteggio effettivo a causa dell'uguaglianza nei riferimenti a cui l'analizzatore ha preferito filtrali.

nei tuoi screenshot hai selezionato più .dexfile, quindi l'uguaglianza del filtro Analizzatore.

nel nostro progetto stiamo usando il file dependencies.gradle centralizzato, quindi non c'è possibilità di versione diversa. Quindi, pensi che anche se abbiamo lo stesso / esatto insieme di dipendenze e le loro versioni nei moduli funzione, aumenterà il conteggio dei metodi di riferimento?

Teoricamente NON dovrebbe aumentare il conteggio dei metodi di riferimento. MA , come ho spiegato, l' esperienza degli sviluppatori ha un grande impatto sul risultato finale.

Team Analyzer dovrebbe verificare e risolvere i problemi di prestazioni prima del rilascio come

  • regole proguard
  • risorse ridotte e minimizzate
  • AndroidManifest.xml
  • impostazioni del grado

Ora voglio chiarire in che modo l' esperienza degli sviluppatori e la manutenzione del codice influiscono sul risultato finale. ANCHE se il tuo APK utilizza dipendenze centralizzate

figura 3

nell'esempio sopra, sono aumentato 5.1knel conteggio dei metodi di riferimento ANCHE SE avevo dipendenze centralizzate !!!!!

Com'è possibile ?

La risposta è: ho appena aggiunto un .jarfile inutile e nascosto nella libsdirectory del progetto. altrettanto facile come puoi vedere ho influenzato il risultato finale.

Come puoi vedere, l' esperienza degli sviluppatori influisce sul risultato finale. Di conseguenza, praticamente è possibile che i metodi di riferimento vengano aumentati, anche se teoricamente NON dovrebbero .

E perché non c'è differenza nel conteggio dei metodi di riferimento quando compilo solo il modulo 'app' disabilitando la compilazione parallela? Dovrebbe essere diminuito poiché sarebbero state utilizzate solo le dipendenze del modulo "app", giusto?

la compilazione non ha alcuna relazione con i metodi di riferimento conta.it rispetta ciò che lo sviluppatore desidera rispettare.


Conclusione

Ho coperto tutte le possibilità intorno al problema. In effetti, può essere emerso da diverse situazioni e uno sviluppatore utilizzando questa linea guida può risolvere il problema.

  • Spero che abbiate scoperto perché i metodi di riferimento sono stati aumentati e perché in alcuni casi potrebbe essere drasticamente aumentato.
  • I moduli hanno i loro gradi di aumento e dipendenze e moduli di aumento della modularizzazione. pertanto, questi riferimenti ai metodi.
  • La modulazione influisce in realtà sulle prestazioni delle app ignorabili, ma migliora notevolmente la manutenzione delle app.
  • L'esperienza degli sviluppatori nella modularizzazione influisce fortemente anche sul risultato finale.

NOTA IMPORTANTE: quasi tutte le dichiarazioni sono le mie indagini e ricerche. in effetti, potrebbero esserci errori e guasti e verranno aggiornati per aggiungere molte più informazioni in futuro.



Grazie signor AF, speravo di ottenere la risposta dopo "Questa domanda mi viene in mente che i metodi di riferimento contano ciò che riguarda la profondità dell'eredità? La risposta è", ma non hai risposto. Potete per favore approfondire il motivo per cui la profondità dell'eredità aumenta il conteggio del metodo di riferimento? Come nel nostro caso, non abbiamo aggiunto alcun livello aggiuntivo, ma abbiamo semplicemente diviso il modulo "app". Esiste la possibilità di aumentare il conteggio dei metodi di riferimento nel caso in cui un modulo funzione acceda ai metodi di un altro modulo funzione tramite il modulo "app", è questo il motivo?
Rohit Surwase,

La risposta di @RohitSurwase è il resto dell'affermazione: la profondità dell'ereditarietà non aumenta i riferimenti ai metodi, la modularizzazione in tal senso e la modularizzazione in quanto profondità dell'ereditarietà.
Mr.AF

@RohitSurwase, una funzione che accede a un'altra funzione in un altro modulo in realtà non aumenta il conteggio dei metodi di riferimento. il motivo principale per aumentare il conteggio dei metodi di riferimento è Grado e dipendenze di cui ogni modulo ha bisogno.
Mr.AF

@RohitSurwase indichi buoni consigli sulla relazione da modulo a modulo. infatti, se 2 moduli hanno troppe relazioni e metodi referenziati, dovrebbero essere combinati per prestazioni migliori. in realtà il modulo deve essere indipendente in termini e concetti.
Mr.AF

1
@RohitSurwase come ho detto, il vaso non utilizzato potrebbe non essere il tuo caso. Qualcosa che voglio dire è esperienza degli sviluppatori ed è possibile, la possibilità può essere emersa da diverse fonti. e ho elencato tutte le possibili fonti di cui hai bisogno per cercarlo
Mr.AF

2

Rispondere alla mia domanda come la soluzione mi è appena scattata in mente, anche se questo non è stato provato ma avrebbe funzionato, sicuramente o molto probabilmente. :) La risposta data da Mr.AF è stata molto utile per raggiungere una soluzione finale. Parla del perché? ma non come evitarlo o come migliorarlo.

Ecco un modo per recuperare il conteggio del metodo di riferimento originale / effettivo -

Non dipende da come modularizziamo l'app ma da come aggiungiamo dipendenze. Se aggiungiamo una dipendenza usando ' implementazione ', quella dipendenza rimane privata al modulo e nessun altro modulo può usarla. E se aggiungiamo la stessa dipendenza usando ' api ' (uguale a 'compilazione' deprecata) allora diventa pubblica e altri moduli dipendenti possono usarla. Dato che stiamo usando 'implementazione' per aggiungere dipendenze in ciascun modulo in un progetto multi-modulo, ogni modulo ha tutte le dipendenze richieste come autosufficiente, questa è la ragione per cui può essere compilato individualmente. Ciò comporta una riduzione dei tempi di compilazione / compilazione poiché è possibile compilare solo moduli modificati. Ma l'uso di "implementazione" aumenta il conteggio dei metodi di riferimento poiché ci sono così tanti metodi di riferimento duplicati.

Quindi, se il tempo di costruzione non è un problema, ma è il conteggio dei metodi di riferimento, allora puoi disegnare l'albero delle dipendenze di tutti i moduli ed evitare di aggiungere una dipendenza duplicata usando 'api' nel modulo base. In questo modo anche il modulo superiore può utilizzare la dipendenza aggiunta dal modulo base che eviterà i duplicati. Ricorda, questo aumenterebbe il tempo di costruzione.

Siamo in grado di ottenere entrambi se potessimo distinguere le dipendenze per il debug e la versione di rilascio . Aggiungi tutte le dipendenze usando 'implementazione' per il debug build e aggiungi solo le dipendenze richieste e ottimizzate per il build del rilascio usando 'api' . In questo modo la generazione del debug sarà più veloce e la generazione del rilascio sarà più lenta, il che è conveniente.

Nota: aggiornerei questa risposta una volta capito come fornire dipendenze separate per il debug e la versione di rilascio.


mi è piaciuto materiali buoni.
Mr.AF

0

Vedo tutta la differenza nel tuo pacchetto "com". È possibile espandere e confrontare quali classi esatte sono state ridotte. Se si crea con l'ultimo R8, è possibile rimuovere un po 'di codice per impostazione predefinita. Quando si inseriscono alcune classi nel modulo restringitore, non si sa se le classi / i metodi pubblici possono essere rimossi o devono rimanere per l'uso in un altro modulo. inserisci qui la descrizione dell'immagine


Sì, ho ampliato e verificato ogni pacchetto, incluso "com". La principale preoccupazione è perché l'aggiunta del conteggio dei metodi referenziati individualmente è diversa dal conteggio totale dei metodi referenziati in Apk Analyzer?
Rohit Surwase,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.