2012-09-17 11 views
7

In C++ normalmente installerei 2 build: debug e release con rispettivamente DEBUG e RELEASE predefiniti. Vorrei quindi utilizzare queste definizioni per determinare i valori costanti, come la registrazione abilitata/disabilitata, l'URL del server e così via.Build di debug di rilascio per l'applicazione Android

In questo momento, in Java/Android commento alcune cose prima di rilasciare. Non è un buon modo, lo so. Potrei dimenticare qualcosa.

Qual è una pratica comune per garantire che nulla venga dimenticato quando si crea una versione di rilascio (firmata) o una versione di debug (senza firma)?

risposta

8

Non c'è (per impostazione predefinita) qualsiasi preprocessore per Java, in modo che nessun #ifdef roba in fase di compilazione. Ma se non ti dispiace lasciare il codice di debug nella vostra app, allora si può controllare se app è di rilascio o di debug in fase di esecuzione con questo codice:

Boolean release = (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE); 

che controlla debuggable valore del flag. E detto flad è impostato automaticamente su false per build di versioni e true per le build di debug.

Se si desidera eliminare qualche codice di debug, è possibile provare a utilizzare ProGuard per rimuovere determinate classi o metodi. E per impostazione predefinita ProGuard è coinvolto nel processo di compilazione solo per le build di rilascio.

+3

Si consiglia di utilizzare BuildConfig.DEBUG poiché ciò avviene in fase di compilazione, la soluzione funziona in runtime. Pertanto il codice di registrazione sarà all'interno del pacchetto. In fase di compilazione, il compilatore java non prenderà in considerazione il codice all'interno dell'istruzione if. –

+0

Si prega di controllare la mia risposta aggiornata. Questo chiarirà che è vero =) –

+0

Si può anche prendere in considerazione la definizione del proprio 'globale pubblico finale statico booleano DEBUG = falso;' per un maggiore controllo sul risultato ... (ci sono stati casi in cui 'BuildConfig.DEBUG 'non stava veramente riflettendo lo stato del sistema). –

14

Se si esegue l'applicazione da Eclipse, sarà sempre un debug.

Quando si esporta l'applicazione (Android Tools -> Esporta (ONU) hanno firmato Application Package)

Se vuoi sapere dinamicamente se il suo rilascio o di debug, è possibile utilizzare BuildConfig.DEBUG (Si trova nel gen cartella, non so se questo è supportato da tutti i livelli di API)

come come segue:

if (BuildConfig.DEBUG) { 
    Log.d(TAG, "Text"); 
} 

Se si guardano le bytecode generato si vedrà la seguente (in modalità debug):

public class Sample{ 

    private static final boolean LOG_ENABLED = true; 

    public static void main(String args[]){ 
     if (BuildConfig.DEBUG){ 
      System.out.println("Hello World"); 
     } 
    } 
} 

produce i seguenti bytecode:

public class Sample extends java.lang.Object{ 
    public Sample(); 
     Code: 
     0: aload_0 
     1: invokespecial #1; //Method java/lang/Object."<init>":()V 
     4: return 

    public static void main(java.lang.String[]); 
     Code: 
     0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 
     3: ldC#3; //String Hello World 
     5: invokevirtual #4; //Method Java/io/PrintStream.println(Ljava/lang/String;)V 
     8: return 

} 

E se il BuildConfig.DEBUG è falsa

public class Sample extends java.lang.Object{ 
    public Sample(); 
     Code: 
     0: aload_0 
     1: invokespecial #1; //Method java/lang/Object."<init>":()V 
     4: return 

    public static void main(java.lang.String[]); 
     Code: 
     0: return 
} 
0

Io di solito creare una classe di registro separato in cui ho impostato una variabile DEBUG statica. Ora tutto quello che devo fare prima di ottenere una build di produzione è impostare la variabile DEBUG su false.

public class Log { 
    public final static String LOGTAG = "APP NAME"; 

     public static final boolean DEBUG = true; 

     public static void v(String msg) { 
     android.util.Log.v(LOGTAG, msg); 
     } 

     public static void e(String msg) { 
     android.util.Log.e(LOGTAG, msg); 
     } 

     public static void d(String msg) { 
      android.util.Log.d(LOGTAG, msg); 
     } 
} 

Per la registrazione -

if(Log.DEBUG) Log.v("In some function x. Doing y."); 
+0

Ho 6 costanti di registrazione nel mio oggetto di registrazione. Ho impostato 2 di questi su false quando ho creato un rilascio. – Pijusn

0

Stavo affrontando lo stesso problema di ogni altra volta che stavo eseguendo il progetto come applicazione Android che usava per aprire in modalità debugger, ma poi il problema è stato risolto.

-Se si sta lavorando in eclissi, è necessario utilizzare Java EE prospettiva -Instare solo selezionare prospettiva Java.

-Pulire la tua app. -installare l'app dal dispositivo. -Riavvia il tuo dispositivo (proprio così che non viene memorizzata la cache) -Esegui la tua app.

La modalità debugger non verrà visualizzata questa volta. Copiare l'apk generato nella cartella bin e provarlo su altri dispositivi come pure

0

ho trovato un modo per emulare decentemente una direttiva al preprocessore:

Nel mio Gradle buildTypes io definisco:

release { 
    buildConfigField "boolean", "isDebug", "false" 
    ... 
} 

debug { 
    buildConfigField "boolean", "isDebug", "true" 
    ... 
} 

poi, nel mio codice, lo faccio come segue:

if (BuildConfig.isDebug) { 
    ... do debug stuff ... 
} 

e, se necessario, naturalmente:

012.
else { 
    ... do release stuff ... 
} 

Entrambi i blocchi sono presenti nel debug APK, ma quando si costruisce una versione release, Proguard è abbastanza intelligente per determinare che il blocco debug può essere rimosso quanto dipendente di un if (false) (anch'esso rimosso dalla codice risultante).

caso si chiama alcune classi specifiche per il debug dal blocco debug e solo da lì, sarà messo a nudo fuori dalla risultante APK in quanto sono considerati inutilizzati, e questo anche un punto interessante: il codice non può essere temperato in un certo modo userebbe quel codice.

È possibile determinare tutto ciò verificando i file di output di Proguard nei file dump, mapping e usage.

Problemi correlati