2011-12-20 8 views
11

Ho cercato di mantenere un progetto di gioco abbastanza indipendente dalla piattaforma, quindi l'ho diviso in tre progetti dal livello basso a quello superiore di Android come quello: motore , gioco, gioco Android.Attività Android in Eclipse/ADT con dipendenze di progetto (risoluzione XY fallita)

Le classi coinvolte/interfacce per l'errore sono quelli:

  1. progetto motore (livello basso) definisce questa interfaccia:

    com.myteam.engine.IGame 
    
  2. (livello medio) progetto piattaforma di gioco indipendente definisce quelle classi:

    com.myteam.myproject.Game 
    com.myteam.myproject.MyProject (derived from com.myteam.myproject.Game) 
    
  3. (livello superiore) Projec Android t implementa l'attività, ecc .:

    com.myteam.myproject.android.MyAndroidActivity (using com.myteam.myproject.MyProject) 
    

Tutti compila bene e funziona perfettamente sotto Windows (con un altro progetto di Windows al livello 3 con i primi due).

Tuttavia, quando viene eseguito con ADT, non viene eseguito in fase di esecuzione all'avvio dell'attività. L'app Android mostra semplicemente uno stack di chiamate con un'eccezione "NoClassDefFoundError com.myteam.myproject.MyProject".

L'eccezione sembra essere causato dalla sua classe super (o l'interfaccia super-class') durante il caricamento/risolvere come l'uscita LogCat rivela:

12-20 19:51:51.897: D/ddm-heap(218): Got feature list request 
12-20 19:51:52.207: I/dalvikvm(218): Failed resolving Lcom/myteam/myproject/Game; interface 18 'Lcom/myteam/engine/IGame;' 
12-20 19:51:52.217: W/dalvikvm(218): Link of class 'Lcom/myteam/myproject/Game;' failed 
12-20 19:51:52.227: W/dalvikvm(218): Unable to resolve superclass of Lcom/myteam/myproject/MyProject; (52) 
12-20 19:51:52.227: W/dalvikvm(218): Link of class 'Lcom/myteam/myproject/MyProject;' failed 
12-20 19:51:52.227: E/dalvikvm(218): Could not find class 'com.myteam.myproject.MyProject', referenced from method com.myteam.myproject.android.MyAndroidActivity.onCreate 
12-20 19:51:52.227: W/dalvikvm(218): VFY: unable to resolve new-instance 54 (Lcom/myteam/myproject/MyProject;) in Lcom/myteam/myproject/android/Youcode_AndroidActivity; 
12-20 19:51:52.227: D/dalvikvm(218): VFY: replacing opcode 0x22 at 0x0008 
12-20 19:51:52.227: D/dalvikvm(218): Making a copy of Lcom/myteam/myproject/android/Youcode_AndroidActivity;.onCreate code (88 bytes) 

Ho provato ad aggiungere i due primi progetti nell'ambito del "Build Percorso/Ordine ed esportazione "Le impostazioni del progetto Eclipse del progetto di gioco Android come descritto in altri post e forum, ma non cambia nulla.

La mia impressione è che le impostazioni di Manifesto o Progetto necessitino di un'altra menzione delle dipendenze pacchetto/classe per l'imballaggio di apk o il tempo di esecuzione. Qualche idea?

+0

Hai controllato se .apk contiene classi che non sono state trovate? – bart

+1

Ho quasi lo stesso problema di te: un progetto Android che dipende da progetti solo Java. Fino ad oggi (quando ho aggiornato gli strumenti di Android SDK r17 da r16), sono riuscito a farlo funzionare con Proprietà progetto-> Percorso di costruzione Java-> Progetti. Ma ora ricevo la stessa eccezione che hai segnalato. Ho presentato una segnalazione di bug: http://code.google.com/p/android/issues/detail?id=27882 – jfritz42

+0

Wow stavo andando matto con questo problema. Fortunatamente il link di jfritz42 aveva la risposta di cui avevo bisogno. Thx man. – tulio84z

risposta

2

Aggiungi il nome dei tuoi progetti dipendenti al file .claspath del tuo progetto Android. così:

<?xml version="1.0" encoding="UTF-8"?> 
<classpath> 
    <classpathentry kind="src" path="src"/> 
    <classpathentry kind="src" path="gen"/> 
    <classpathentry combineaccessrules="false" kind="src" path="/DependentProject1"/> 
    <classpathentry combineaccessrules="false" kind="src" path="/DependentProject2"/> 
    <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> 
    <classpathentry kind="output" path="bin"/> 
</classpath> 
2

ho cercato di trovare una soluzione semplice per questo molto tempo fa, per quanto posso dire, l'unico modo per rendere ADT esportare l'apk finale con le classi della libreria dipendente è esplicitamente aggiungi tutto il tuo lib.jar esterno (generato dagli altri tuoi progetti) nel percorso di generazione del tuo progetto Android.

L'attuale versione di Eclipse ADT plugin ha un molto poco flessibile predefinito ciclo di vita build (in particolare in fase Dexing), a quanto pare non supporta progetto raggruppa diversi da questi tre tipi di progetto Android insieme (classico, biblioteca e test). In altre parole, ADT non sa come costruire il tuo progetto Android con un progetto normale dipendente da java sotto il percorso di generazione e aggiungere automaticamente il lib.jar generato dal progetto dipendente nel percorso di costruzione del tuo progetto principale (anche se li aggiungi all'ordine ed Esporta elenco), a meno che non si aggiunga esplicitamente il file lib.jar esterno. Supponiamo di aggiungere C: \ workspace \ game \ target \ game.jar e C: \ workspace \ engine \ target \ engine.vaso in vostro android-game percorso di generazione del progetto, comando per generare il file dex dovrebbe essere qualcosa di simile:

java [-Xmx1024M, -jar, C:\android-sdk-r16\platform-tools\lib\dx.jar, --dex, --output=C:\workspace\android-game\target\classes.dex, C:\workspace\android-game\target\classes, C:\workspace\game\target\game.jar, C:\workspace\engine\target\engine.jar] 

Se si prevede di adottare alcuni strumenti di compilazione esterni per gestire il tuo progetto di ciclo di vita di generazione, lo so Maven fornire configurazione più flessibile sul ciclo di vita di build di Android. Supporta il progetto multi-modulo (raggruppamento di progetti) e può gestire correttamente la normale dipendenza del progetto Java.

Le mie conoscenze si basano su Eclipse, in attesa di sentire alcuni rumori da fonte Android o altri utenti di IDE sofisticati.

Aggiornamento da ADT 17.0.0:

L'ultima versione SDK r17 con ADT 17.0.0 sostiene per gestire questo casi d'uso corretto ora:

Eclipse specifico cambia

La dinamica Il contenitore del classpath chiamato "Progetti di libreria" è stato rinominato "Dipendenze da Android" in quanto ora contiene più di un semplice progetto di biblioteca.

Ora il contenitore verrà popolato con progetti solo Java a cui fanno riferimento i progetti di libreria. Se tali progetti Java fanno riferimento anche ad altri progetti Java e/o file jar, verranno aggiunti automaticamente (anche i file jar referenziati tramite librerie utente sono supportati).

Importante: questo accade solo se i riferimenti sono impostati per essere esportati nel progetto di riferimento. Si noti che questo non è l'impostazione predefinita quando si aggiunge un progetto o un file jar a un percorso di generazione del progetto. I progetti di libreria (e il contenuto dei file libs/*. Jar) vengono sempre esportati. Questo cambiamento influisce solo sui progetti Java e sui propri file jar.

Ancora una volta, i duplicati (sia progetti che file jar) vengono rilevati e rimossi.

Verificare il changelog.

1

Il percorso di creazione Java del progetto di livello intermedio include il progetto di basso livello, credo. Hai controllato il progetto di basso livello per lì (scheda "Ordine ed esportazione")? In caso contrario, la dipendenza del progetto di basso livello non viene inoltrata al progetto di alto livello, esclusa IGame dall'APK, che in realtà attiva l'errore.

Tuttavia, questa soluzione AFAIK non funzionerà se i progetti contengono elementi specifici di Android come risorse e simili.

0

Dubito di te e del tuo progetto. Dal mio punto di vista, vedo che hai un buon design. Ma perché stai lavorando con Build Path/Order and Export? Onestamente non sono mai andato a quella scheda dal primo giorno in cui ho lavorato con Eclipse.

Per importare i file jar come librerie, utilizzare la scheda Libraries -> aggiungere jar esterni.

E mi dispiace non sapere la programmazione del gioco, questo è solo un suggerimento: assicurati che il tuo motore si adatti a ciò che supporta Android. Ad esempio, Android non supporta javax.imageio. In caso contrario, l'app può essere compilata con jar esterni, ma può essere arrestata in runtime.

12

ho una a tre livelli Android/Java app, quasi proprio come te:

  1. Java-unico progetto per la comunicazione di rete a basso livello
  2. Java unico progetto alle caratteristiche astratte del progetto a basso livello
  3. Android

Ogni cosa di cui sopra è un progetto Eclipse separata contenuta in un unico spazio di lavoro.

Ecco cosa dovete fare:

  1. nell'ambito del progetto della App properties-> Java Costruire Path-> Progetti, aggiungere il Java solo progetti
  2. nell'ambito del progetto della App properties-> Java Build Path -> ordine e di esportazione, controllare i-only Java progetti (che li segna per l'esportazione)

Ora la vostra applicazione deve costruire e gestire, senza eccezioni o NoClassDefFoundErrorVFY errori come il seguente:

03-27 21:10:17.120: W/dalvikvm(420): VFY: unable to find class referenced in signature (Labstractionlayer/BaseStationManager;) 
03-27 21:10:17.120: W/dalvikvm(420): VFY: unable to find class referenced in signature (Labstractionlayer/BaseStationManager;) 
03-27 21:10:17.160: I/dalvikvm(420): Failed resolving Lcom/demo/log/AndroidLogWrapper; interface 253 'Lcommon/Logger/LogWrapper;' 
03-27 21:10:17.160: W/dalvikvm(420): Link of class 'Lcom/demo/log/AndroidLogWrapper;' failed 
03-27 21:10:17.160: E/dalvikvm(420): Could not find class 'com.demo.log.AndroidLogWrapper', referenced from method com.demo.Application.onCreate 
03-27 21:10:17.160: W/dalvikvm(420): VFY: unable to resolve new-instance 218 (Lcom/demo/log/AndroidLogWrapper;) in Lcom/demo/Application; 
03-27 21:10:17.170: D/dalvikvm(420): VFY: replacing opcode 0x22 at 0x0003 
03-27 21:10:17.170: D/dalvikvm(420): VFY: dead code 0x0005-003c in Lcom/demo/Application;.onCreate()V 
03-27 21:10:17.170: D/AndroidRuntime(420): Shutting down VM 
03-27 21:10:17.170: W/dalvikvm(420): threadid=1: thread exiting with uncaught exception (group=0x40015560) 
03-27 21:10:17.180: E/AndroidRuntime(420): FATAL EXCEPTION: main 
03-27 21:10:17.180: E/AndroidRuntime(420): java.lang.NoClassDefFoundError: com.demo.log.AndroidLogWrapper 

BTW, prima di ADT r17, è necessario solo eseguire il passaggio 1 sopra (aggiungere i progetti solo Java). Ma a partire da r17, è necessario anche eseguire il passaggio 2 (contrassegnare i progetti solo Java per l'esportazione).

0

So che questa è una vecchia questione, ma ho trovato un nuovo modo di imbattersi in questo errore, che può aiutare gli altri con aggiornamenti recenti.

Ho ricevuto questo errore dall'utilizzo di una commutazione caso/caso sul R.id. "costanti". Gli ultimi aggiornamenti non considerano le dichiarazioni R.java come costanti nel codice anche se sono dichiarate definitive. Quello che succede è che .apk compilerà e installerà ma produrrà quegli errori Lcom.

Per risolvere questo (in Eclipse) viene messo il cursore sull'interruttore dichiarazione e utilizzare Ctrl + 1 per convertire l'interruttoread una lista di se poi altro 's. Nota Se si dispone nidificato pause all'interno di una caso dichiarazione è necessario riscrivere quel blocco di codice (probabilmente con più altro 's).