2012-10-21 15 views
7

ACRA stesso si blocca con un problema strano:È possibile utilizzare ACRA in un progetto di libreria?

IllegalStateException: Cannot access ErrorReporter before ACRA#init

Ho un app con ACRA 4.3.0 che funziona perfettamente. Ho cambiato l'intera app in una libreria, quindi posso apportare varianti minori. Ho creato un nuovo progetto completamente vuoto diverso da un manifest e collegamenti a questa nuova libreria. Per qualsiasi altro tentativo, in AcraApplication.java è necessario rimuovere la riga "resToastText = R.string.crash_toast_text" e aggiungere una nuova riga sotto Acra.init (this);

ACRA.getConfig().setResToastText(R.string.crash_toast_text);

Il progetto si basa fine e in eseguire il debug ho confermato ACRA.init (questo); viene eseguito prima del codice del mio programma principale e prima che si verifichi l'errore. Nel programma principale, nel punto in cui abbiamo fissato alcuni dati personalizzati:

ACRA.getErrorReporter().putCustomData("Orientation", "L");

Essa provoca l'incidente (o, più precisamente, ACRA si causa l'errore) e non viene generato alcun rapporto di ACRA.

Qualche idea su cosa provare in seguito o indicazioni su dove cercare? Potrebbe essere ACRA incompatibile con le librerie, che in questo caso, posso estrarlo diversamente da una maniglia, ma in qualche modo sconfigge lo scopo della libreria.


Soluzione: Invece di aggiungere la riga sotto Acra.init(this); aggiungere queste tre linee prima della linea di init:

ACRAConfiguration config = ACRA.getNewDefaultConfig(this); 
config.setResToastText(R.string.crash_toast_text); 
ACRA.setConfig(config); 

ACRA.init(this); 

Nota questo funziona solo in v4.3.0 e versioni successive.

risposta

1

Ho avuto lo stesso problema, è stato causato dalla confusione del proguard.

La soluzione è quella di aggiungere le personalizzazioni di seguito per proguard.cfg di file (tratto da ACRA pagina wiki here):

Nota che l'ACRA.init() dovrebbe rimanere al principio:

@Override 
    public void onCreate() { 
    ACRA.init(this); 
    ACRA.getErrorReporter().setReportSender(new MySender()); 

    super.onCreate(); 
    } 

proguard.cfg:

#ACRA specifics 
# we need line numbers in our stack traces otherwise they are pretty useless 
-renamesourcefileattribute SourceFile 
-keepattributes SourceFile,LineNumberTable 

# ACRA needs "annotations" so add this... 
-keepattributes *Annotation* 

# keep this class so that logging will show 'ACRA' and not a obfuscated name like 'a'. 
# Note: if you are removing log messages elsewhere in this file then this isn't necessary 
-keep class org.acra.ACRA { 
    *; 
} 

# keep this around for some enums that ACRA needs 
-keep class org.acra.ReportingInteractionMode { 
    *; 
} 

-keepnames class org.acra.sender.HttpSender$** { 
    *; 
} 

-keepnames class org.acra.ReportField { 
    *; 
} 

# keep this otherwise it is removed by ProGuard 
-keep public class org.acra.ErrorReporter 
{ 
    public void addCustomData(java.lang.String,java.lang.String); 
    public void putCustomData(java.lang.String,java.lang.String); 
    public void removeCustomData(java.lang.String); 
} 

# keep this otherwise it is removed by ProGuard 
-keep public class org.acra.ErrorReporter 
{ 
    public void handleSilentException(java.lang.Throwable); 
} 
+0

Ciao, anche con queste righe nel mio proguard.cfg, ho ancora un "NoSuchFieldError: SILENT" nella mia versione. Non riesco a capirlo – Arnaud

1

assicurarsi di aver aggiunto nel manifest

<application 
    android:name="com.test.MyApp" 

e si dispone di classe di applicazione che in seguito

import org.acra.ACRA; 
import org.acra.ReportField; 
import org.acra.ReportingInteractionMode; 
import org.acra.annotation.ReportsCrashes; 

import android.app.Application; 

@ReportsCrashes(formKey = "", mailTo = "your_email_address", customReportContent = { 
      ReportField.APP_VERSION_CODE, ReportField.APP_VERSION_NAME, 
      ReportField.ANDROID_VERSION, ReportField.PHONE_MODEL, 
      ReportField.CUSTOM_DATA, ReportField.STACK_TRACE, ReportField.LOGCAT }, mode = ReportingInteractionMode.TOAST, resToastText = R.string.crash_toast_text) 
    public class MyApp extends Application 
    { 
     @Override 
     public void onCreate() 
     { 
      super.onCreate(); 
      ACRA.init(this); 
     } 
    } 
1

Nel mio caso mi mancava @ReportCrashes config ... Spero che questo funzionerà

@ReportsCrashes(
    formUri = "uploadurl", 
    reportType = HttpSender.Type.JSON, 
    httpMethod = HttpSender.Method.POST, 
    formUriBasicAuthLogin = "llenigingeneyederrownlys", 
    formUriBasicAuthPassword = "1a35b13f9f54271d23a9aed988451182e5b97211", 
    formKey = "", // This is required for backward compatibility but not used 
    customReportContent = { 
      ReportField.APP_VERSION_CODE, 
      ReportField.APP_VERSION_NAME, 
      ReportField.ANDROID_VERSION, 
      ReportField.PACKAGE_NAME, 
      ReportField.REPORT_ID, 
      ReportField.BUILD, 
      ReportField.STACK_TRACE 
    }, 
    mode = ReportingInteractionMode.TOAST, 
    resToastText =R.string.msg 

)