2013-07-22 6 views
7

Questa domanda potrebbe essere soggettiva, ma credo StackOverflow è ancora il posto migliore per chiedere:Costruire in Android/IntelliJ/Jenkins

Il problema di dominio è "la programmazione Android avanzati". Non ho bisogno di informazioni su come impostare un singolo progetto Android, su come utilizzare i progetti di libreria o su come usare ANT per costruire un progetto normale.

Supponiamo di avere un'app in esecuzione, un normale progetto Android (IDE di scelta è IntelliJ, ma non dovrebbe essere un problema) costruito da Jenkins/Ant/Proguard. Il risultato di questa build è l'APK finale che avresti inserito nel Play Store.

Ora immagina di aver bisogno di questa App come versione gratuita ea pagamento. Nessun problema finora, è sufficiente inserire tutto il codice condiviso in un progetto di libreria e creare due progetti figlio, uno con un'app.java che abilita i controlli di licenza, l'altro ad es. limitando l'uso.

Ora immagina di voler indirizzare anche Amazon, magari una versione di comunicato stampa, ecc. Quindi il tuo codice inizia a divergere, con ancora molte cose condivise, ma alcune parti sono specifiche per es. il mercato che scegli come target.

In C# ci sono "istruzioni di compilazione condizionale", come "SE PLAY_STORE ...". C'è qualcosa di simile per Java/Android. Inoltre, giocano bene con ANT e il processo di costruzione.

Ma non sono limitato alla compilazione condizionale. L'approccio "un progetto per mercato" è diverso. Sto solo cercando di capire come gestisci queste varie "configurazioni di build" in modo sostenibile. Significa che funziona per 15 progetti, destinati a 3 mercati in 2 versioni (GRATUITO e PAGATO). Spero che tu capisca cosa sto suggerendo. Il codice è molto simile per tutte le app, ma con l'esempio sopra avrò 90 APK diversi - con questi numeri il "commentare manualmente nel codice sorgente richiesto solo da questa build, ecc" non lo taglia più.

Quindi suggerimenti, strumenti, parole di ricerca, esperienze con questi domini problematici (ad esempio MAVEN, mi aiuterebbe con uno di questi, oppure gli script ANT + che generano build.xml vanno meglio). Un altro esempio, se ho un progetto Android "reale" per tutti i mercati di destinazione, questo mi permetterebbe di fare quasi tutto. Ma ovviamente, se aggiungo una nuova pagina nel livello più basso (ad esempio una pagina di stampa) dovrei andare in 90 Manifest.xml per aggiungere la pagina ...

Grazie per qualsiasi aiuto con questo, Chris

PS: vorrei aggiungere alcuni link che ho trovato su questo tema in fondo, se qualcuno si imbatte in questa domanda, mentre non ci sono risposte, questo potrebbe essere un "prima di leggere questo" capitolo

http://www.asyncdev.net/2011/02/android-dev-prod-builds/

http://www.slf4j.org/ (correlato nel "JAR messo in t o fornire "modo IMPL"

(SLF4J è solo un buon approccio per ridurre le dipendenze e fornire la configurazione durante l'implementazione, semplicemente aggiungendo un JAR differente. Usare qualcosa di simile potrebbe essere eccessivo per i propri progetti, ma sarebbe un modo. Per esempio. per l'interfaccia di scrittura della licenza e un po 'di codice come SLF4J, quindi fornire PressRelease.jar o Productive.jar nella cartella Lib durante la compilazione, cambiando il modo in cui l'app si comporta ...)

+0

Hai trovato una soluzione per questo? Sto anche cercando di capire il modo migliore per raggiungere questo obiettivo. Grazie – LocoMike

+0

No, ancora provando cose. Molto probabilmente finirò con, ad es. una combinazione di StaticLoggerBinder -> JAR -> Replace_On_Build -> ConfigureByStaticBool (ma al posto del tipo Logger di BoolService).Devi andare nella slf4j per capire la frase :-) –

+0

Quindi ricostruire (immette) slf4j fornendo bool invece di logger –

risposta

1

Questa domanda è in qualche modo basata in quanto in un progetto complesso ci sono sempre più di 1 soluzioni adatte.

Preambolo

Cercherò di spiegare alcuni principi che ho usato per distribuire Linderdaum Puzzle HD. Il gioco ha versioni a pagamento e gratuite che differiscono non solo nel codice, ma nell'interfaccia utente e nei contenuti del gioco.

Il gioco è rilasciato per due piattaforme e diversi negozi (che tutti hanno meccanismo di autorizzazione diversa):

Android:

  1. Google Play (2: libero + pagamento)
  2. AndroidPIT (2 : gratis + pagato)
  3. SlideMe (1: gratuito)
  4. Samsung negozio (1: gratuito)

Blackberry OS 10

  1. mondo BlackBerry (1: a pagamento)

di Windows

  1. Usiamo questa versione per sviluppo e test su un PC (1: a pagamento)

Questo ci dà 8 diversi distri pacchetti di bution.

Ambiente

nostra toolchain produzione si basa su git e TeamCity. Non vengono utilizzati strumenti speciali (come Maven, Gradle).

Soluzione

L'end-point del nostro flusso di lavoro è pagina del progetto TeamCity dove abbiamo tutta costruire configurazioni corrispondenti a 8 pacchetti di distribuzione più alcune aggiuntive costruisce per il debug (vale a dire con i controlli e registri aggiuntivi). Qualsiasi pacchetto può essere creato tramite un'interfaccia web da qualsiasi luogo in un clic.

Per ogni pacchetto è presente un nome di ramo git (condiviso da alcuni pacchetti) in modo che lo TeamCity sappia da dove estrarre i sorgenti. Al momento abbiamo questa rami:

remotes/origin/master 
    remotes/origin/release300-blackberry 
    remotes/origin/release300-master 
    remotes/origin/release300-paid_apps 
    remotes/origin/release300-paid_apps_androidpit 

Qui release300 rappresenta una versione del gioco. Abbiamo molti rami di archivio per questi. Questi non sono rami di sviluppo o funzionalità, ma solo per contenere le modifiche per il particolare pacchetto di gioco. Cioè in paid_apps c'è più contenuto di gioco e paid_apps_androidpit contiene la libreria di licenze AndroidPit.

Lo sviluppo avviene in master e nei rami di funzionalità che vengono uniti nuovamente al livello principale. Quindi avviene un processo di unione.Le direzioni di merge sono (e solo queste direzioni):

master -> release300-master -> release300-paid_apps -> release300-paid_apps_androidpit 
     \ 
     \-> release300-blackberry 

cioè, release300-paid_apps_androidpit ha sostanzialmente lo stesso contenuto release300-paid_apps, tuttavia, aggiunge alcune nuove funzionalità (come la concessione di licenze biblioteca, ecc). E release300-blackberry è completamente separato poiché deve indirizzare i dispositivi con un rapporto di schermo 1: 1 insolito e ha un'interfaccia utente del design speciale. Quindi, questi 5 rami sono usati per costruire i nostri 8 pacchetti di distribuzione.

Non uniamo mai le modifiche da questi rami di rilascio al master. Le correzioni dei bug sono propagate nella stessa direzione.

Ogni pacchetto ha il proprio file di script, I.e. la creazione dell'applicazione gratuita per Google Play è semplice come chiamare lo script Python BuildAndroid.py sul ramo release300-master.

La stessa idea vale per tutti gli altri pacchetti: utilizzare solo un corridore di compilazione della riga di comando di TeamCity su una sola riga.

+2

Grazie, quindi è una configurazione basata su GIT. Ci ho pensato, ma ho deciso contro. Motivo principale: sto usando i sottomoduli GIT e sono un rompicapo quando si cambiano i rami (ma potrei dare un'altra occhiata). Penso che vada con il "progetto separato" per FREE/PRO e config da JAR/AssetFile creato/aggiornato da build_marketA.xml - Ti lancerò se non dovessi rispondere meglio, grazie per lo sforzo. Suono molto buono per progetti standalone (nessun sottomodulo GIT) –

+0

Un'altra domanda però: non hai spazi dei nomi separati GRATIS e PAGATO - per google ad es. ne hai bisogno Quindi i rami non dovrebbero essere difficili da mantenere o cambi solo APK_Namespace in Manifest e mantieni le fonti nello stesso spazio dei nomi (altrimenti diverso pacchetto = cartella in rami diversi) –

+1

Non abbiamo spazi dei nomi speciali. Tutte le differenze tra le versioni FREE e PAID sono inserite nelle filiali. In ogni caso, è molto facile fare fusioni in un'unica direzione, dal ramo padre. –

2

Si dovrebbe dare un'occhiata a

  1. progetti Biblioteca - questo vi aiuterà con una corretta separazione del codice e gioca bene con ant - un'occhiata alla nostra presentazione al droidcon qui: http://skillsmatter.com/podcast/agile-testing/building-your-app-for-multiple-app-stores)
  2. Gradle (aka "nuovo sistema di costruzione") - questo ti aiuterà con condizioni di costruzione più semplici e un'integrazione IDE leggermente migliore (con nuovo Android Studio) vedi ulteriori informazioni qui: http://tools.android.com/tech-docs/new-build-system)

UPD: Come vedo, stai già usando l'LP per i tuoi progetti. Alcuni consigli per rendere questo più facile processo:

  1. Usa manifestmerger.enabled=true

  2. Date un'occhiata a github.com/onepf/OpenIAB

0

Se sei bloccato con ant per ragioni non si possono controllare, prendere in considerazione utilizzando filtri e token. È possibile avere file .java generati da modelli che corrispondono alla configurazione o alla business logic per ciascun tipo. Ecco un esempio ufficiale:

<copy file="${build.dir}/version.txt" toFile="${dist.dir}/version.txt"> 
    <filterset begintoken="%" endtoken="*"> 
    <filter token="DATE" value="${TODAY}"/> 
    </filterset> 
</copy> 

Questo sostituirà il testo @DATE* in ${build.dir}/version.txt con la data corrente e copiare il risultato di ${dist.dir}/version.txt. Questo, insieme ad alcune ramificazioni intelligenti, può darti un preprocessore semipermanente. Il rovescio della medaglia è, naturalmente, che è molto lento (ant in generale è, questo ancora di più).

Vorrei davvero poter raccomandare Gradle, poiché ha questa funzionalità integrata (sapori del prodotto) ma sfortunatamente non è un'opzione seria mentre è in fase di sviluppo attivo. Forse tra qualche mese ma non ora.