it-swarm.com.de

Verwenden Sie try/catch, um zu verhindern, dass die App abstürzt

Ich habe an einer Android-App gearbeitet, die häufig try/catch verwendet, um zu verhindern, dass sie auch an Orten abstürzt, an denen dies nicht erforderlich ist. Zum Beispiel,

Eine Ansicht in xml layout mit id = toolbar wird wie folgt referenziert:

// see new example below, this one is just confusing
// it seems like I am asking about empty try/catch
try {
    View view = findViewById(R.id.toolbar);
}
catch(Exception e) {
}

Dieser Ansatz wird in der gesamten App verwendet. Die Stack-Trace wird nicht gedruckt und es ist wirklich schwer zu finden, was falsch gelaufen ist. Die App wird plötzlich geschlossen, ohne dass eine Stapelverfolgung gedruckt wird.

Ich bat meinen Senior, es mir zu erklären, und er sagte:

Dies dient dazu, Abstürze in der Produktion zu verhindern.

Ich kann dem überhaupt nicht zustimmen. Für mich ist dies nicht der Weg, um Apps vor Abstürzen zu schützen. Es zeigt, dass der Entwickler nicht weiß, was er/sie tut und Zweifel hat.

Wird dieser Ansatz in der Industrie verwendet, um Abstürze von Unternehmensanwendungen zu verhindern?

Wenn try/catch wirklich unser Bedürfnis ist, ist es dann möglich, einen Exception-Handler mit UI-Thread oder anderen Threads zu verknüpfen und dort alles zu fangen? Dies wird, wenn möglich, ein besserer Ansatz sein.

Ja, leerer try/catch ist fehlerhaft und selbst wenn wir Stack-Trace- oder Protokollausnahmen auf dem Server drucken, macht das Blockieren von Codeblöcken in try/catch in der gesamten App für mich keinen Sinn. wenn jede Funktion in einem try/catch eingeschlossen ist.

UPDATE

Da diese Frage viel Beachtung gefunden hat und einige Leute die Frage falsch interpretiert haben (vielleicht, weil ich sie nicht klar formuliert habe), werde ich sie umformulieren. 

Hier ist, was Entwickler hier machen

  • Eine Funktion wird geschrieben und getestet, es kann sich um eine kleine Funktion handeln, die lediglich Ansichten initialisiert oder eine komplexe, nachdem der Test um den try/catch-Block gewickelt ist. Sogar für Funktionen, die niemals eine Ausnahme auslösen.

  • Diese Vorgehensweise wird in der gesamten Anwendung verwendet. Manchmal wird ein Stack-Trace gedruckt und manchmal nur ein debug log mit einer zufälligen Fehlermeldung. Diese Fehlermeldung unterscheidet sich von Entwickler zu Entwickler.

  • Bei diesem Ansatz stürzt die App nicht ab, das Verhalten der App wird jedoch unbestimmt. Selbst manchmal ist es schwer zu verfolgen, was schief gelaufen ist.

  • Die eigentliche Frage, die ich gestellt habe, war: Ist es in der Branche üblich, Abstürze der Unternehmensanwendungen zu verhindern? Und ich frage nicht nach leeres try/catch. Ist es so, dass Benutzer Anwendungen lieben, die nicht abstürzen, als Anwendungen, die sich unerwartet verhalten? Weil es wirklich darauf ankommt, entweder abstürzen zu lassen oder dem Benutzer einen leeren Bildschirm zu zeigen, oder das Verhalten, das dem Benutzer nicht bekannt ist.

  • Ich poste hier ein paar Ausschnitte aus dem echten Code

      private void makeRequestForForgetPassword() {
        try {
            HashMap<String, Object> params = new HashMap<>();
    
            String email= CurrentUserData.msisdn;
            params.put("email", "blabla");
            params.put("new_password", password);
    
            NetworkProcess networkProcessForgetStep = new NetworkProcess(
                serviceCallListenerForgotPasswordStep, ForgotPassword.this);
            networkProcessForgetStep.serviceProcessing(params, 
                Constants.API_FORGOT_PASSWORD);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
     private void languagePopUpDialog(View view) {
        try {
            PopupWindow popupwindow_obj = popupDisplay();
            popupwindow_obj.showAsDropDown(view, -50, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    void reloadActivity() {
        try {
            onCreateProcess();
        } catch (Exception e) {
        }
    }
    

Es ist nicht Duplikat der Android-Ausnahmebehandlung am besten Praktiken , dort versucht das OP, eine Ausnahme für ein anderes.__ abzufangen. Zweck als diese Frage.

74
mallaudin

Natürlich gibt es immer Ausnahmen von Regeln, aber wenn Sie eine Faustregel benötigen, dann sind Sie richtig. leere catch blocks sind "absolut" schlechte übungen.

Schauen wir uns zunächst Ihr spezielles Beispiel an:

try {
  View view = findViewById(R.id.toolbar);
}
catch(Exception e) { }

So entsteht ein Verweis auf etwas; und wenn das fehlschlägt ... spielt es keine Rolle; weil diese Referenz gar nicht erst benutzt wird! Der obige Code ist absolut nutzloses Leitungsrauschen . Oder geht die Person, die diesen Code ursprünglich geschrieben hat, davon aus, dass ein zweiter, ähnlicher Aufruf auf magische Weise keine Ausnahme mehr auslöst ?!

Vielleicht sollte das so aussehen:

try {
  View view = findViewById(R.id.toolbar);
  ... and now do something with that view variable ...
}
catch(Exception e) { }

Aber was hilft das schon wieder ?! Es gibt Ausnahmen, um zu kommunizieren bzw. Fehlersituationen innerhalb Ihres Codes zu verbreiten . Das Ignorieren von Fehlern ist selten eine gute Idee. Tatsächlich kann eine Ausnahme folgendermaßen behandelt werden:

  • Sie geben dem Benutzer Feedback. (wie: "der eingegebene Wert ist keine Zeichenfolge, versuchen Sie es erneut"); oder sich auf komplexere Fehlerbehandlung einzulassen
  • Vielleicht ist das Problem irgendwie zu erwarten und kann gemildert werden (zum Beispiel durch eine "Standard" -Antwort, wenn eine "Fernsuche" fehlgeschlagen ist).
  • ...

Um es kurz zu machen: Das Minimum , das Sie mit einer Ausnahme tun, ist, es zu protokollieren/verfolgen; Wenn Sie später mit dem Debuggen eines Problems beginnen, verstehen Sie "OK, zu diesem Zeitpunkt ist diese Ausnahme aufgetreten".

Und wie andere bereits betont haben: Sie vermeiden es auch generell, nach Exception zu fangen (je nach Ebene gibt es gute Gründe, nach Ausnahme und sogar einige Arten von Fehlern auf höchster Ebene, um sicherzustellen, dass nichts verloren geht; je ).

Zum Schluss Zitat Ward Cunningham:

Sie wissen, dass Sie mit sauberem Code arbeiten, wenn sich herausstellt, dass jede von Ihnen gelesene Routine so ziemlich dem entspricht, was Sie erwartet haben. Sie können es als schönen Code bezeichnen, wenn der Code auch den Eindruck erweckt, dass die Sprache für das Problem erstellt wurde.

Lass das einwirken und meditiere darüber. Sauberer Code überrascht Sie nicht . Das Beispiel, das Sie uns zeigen, überrascht jeden , der es betrachtet.

Update bezüglich des Updates, nach dem das OP fragt

try {
  do something
}
catch(Exception e) { 
  print stacktrace
}

Gleiche Antwort: Das "überall" zu tun, ist auch eine schlechte Übung. Weil dieser Code auch den Leser überrascht.

Obenstehendes:

  • Gibt irgendwo Fehlerinformationen aus. Es ist überhaupt nicht garantiert, dass dieses "irgendwo" einem vernünftigen ähnelt. Ziel. Im Gegenteil. Beispiel: In der Anwendung, mit der ich arbeite, werden solche Aufrufe auf magische Weise in unseren Trace-Puffern angezeigt. Abhängig vom Kontext pumpt unsere Anwendung manchmal Tonnen und Tonnen von Daten in diese Puffer. Diese Puffer alle paar Sekunden abschneiden lassen. "Nur Fehler drucken" bedeutet also oft "einfach alle Fehlerinformationen verlieren".
  • Dann: Sie versuchen/fangen nicht, weil Sie können . Sie tun es, weil Sie verstehen, was Ihr Code tut. und du weißt schon: ich sollte versuchen, das Richtige zu tun (siehe die ersten Teile meiner Antwort noch einmal).

Verwenden Sie also try/catch als "Muster", wie Sie es gerade zeigen. ist wie gesagt: immer noch keine gute idee. Und ja, es verhindert Abstürze; führt aber zu jeglichem "undefinierten" Verhalten. Sie wissen, wenn Sie gerade eine Ausnahme abfangen, anstatt richtig damit umzugehen; Sie öffnen eine Dose Würmer; weil Sie möglicherweise auf unzählige Folgefehler stoßen, die Sie später nicht verstehen. Weil Sie das "Grundursachen" -Ereignis früher konsumiert haben; druckte es irgendwo; und das irgendwo ist jetzt weg.

78
GhostCat

Aus der Android Dokumentation :

Lassen Sie uns es als - bezeichnen

Generische Ausnahme nicht abfangen

Es kann auch verlockend sein, faul zu sein, wenn man Ausnahmen fängt und so etwas tut:

try {
    someComplicatedIOFunction();        // may throw IOException
    someComplicatedParsingFunction();   // may throw ParsingException
    someComplicatedSecurityFunction();  // may throw SecurityException
    // phew, made it all the way
} catch (Exception e) {                 // I'll just catch all exceptions
    handleError();                      // with one generic handler!
}

In fast allen Fällen ist es unangemessen, generische Exception oder Throwable abzufangen (vorzugsweise nicht Throwable, da es Fehlerausnahmen enthält). Dies ist sehr gefährlich, da dies bedeutet, dass Ausnahmen, die Sie niemals erwartet haben (einschließlich RuntimeExceptions wie ClassCastException), bei der Fehlerbehandlung auf Anwendungsebene eingehen.

Es verdeckt die Fehlerbehandlungseigenschaften Ihres Codes. Wenn also jemand einen neuen Typ von Exception in den von Ihnen aufgerufenen Code hinzufügt, wird der Compiler Ihnen nicht helfen, zu erkennen, dass Sie den Fehler anders behandeln müssen.

Alternativen zum Fang allgemeiner Ausnahme:

  • Fangen Sie jede Ausnahme separat nach einem einzigen Versuch als separate Fangblöcke. Dies kann umständlich sein, ist aber dennoch vorzuziehen, alle Ausnahmen abzufangen.
    Bearbeiten nach Autor: Dies ist meine Wahl. _ ​​Vorsicht, zu viel Code in den catch-Blöcken zu wiederholen. Wenn Sie Java 7 oder höher verwenden, verwenden Sie multi-catch, um die Wiederholung von gleicher Fangblock.
  • Refaktorieren Sie Ihren Code für eine differenziertere Fehlerbehandlung mit mehreren try-Blöcken. Trennen Sie das IO vom Parsing, behandeln Sie Fehler jeweils separat.
  • Die Ausnahme erneut auslösen. Oft müssen Sie die Ausnahme auf dieser Ebene sowieso nicht fangen, lassen Sie die Methode es einfach werfen.

In den meisten Fällen sollten Sie unterschiedliche Ausnahmetypen nicht auf dieselbe Weise behandeln.

Formatierung/Absatz von dieser Quelle aus leicht verändert.

P.S. Fürchte dich nicht vor Ausnahmen !! Sie sind Freunde!!!

15
Paresh P.

Ich würde dies als Kommentar zu einer anderen Antwort verwenden, aber ich habe noch nicht den Ruf dafür.

Sie haben zu Recht gesagt, dass dies eine schlechte Praxis ist. Tatsächlich zeigt das, was Sie gepostet haben, unterschiedliche Arten von Fehlverhalten in Bezug auf Ausnahmen.

  1. Fehlende Fehlerbehandlung
  2. Generischer Fang
  3. Keine absichtlichen Ausnahmen
  4. Decke Versuchen/fangen

Ich werde versuchen, das alles anhand dieses Beispiels zu erklären.

try {
   User user = loadUserFromWeb();     
   if(user.getCountry().equals("us")) {  
       enableExtraFields();
   }
   fillFields(user);   
} catch (Exception e) { 
}

Dies kann auf verschiedene Weise fehlschlagen, die anders gehandhabt werden sollte.

  1. Die Felder werden nicht ausgefüllt, so dass dem Benutzer ein leerer Bildschirm angezeigt wird und dann ... was? Nichts - mangelnde Fehlerbehandlung.
  2. Es gibt keinen Unterschied zwischen verschiedenen Arten von Fehlern, z. Internetprobleme oder Probleme mit dem Server selbst (Ausfall, fehlerhafte Anfrage, beschädigte Übertragung, ...) - Generic catch.
  3. Sie können keine Ausnahmen für Ihre eigenen Zwecke verwenden, da das aktuelle System dies stört. - Keine absichtlichen Ausnahmen
  4. Unwesentliche und unerwartete Fehler (z. B. null.equals (...)) können dazu führen, dass wesentlicher Code nicht ausgeführt wird. - Decke versuchen/fangen

Lösungen

(1) Zuallererst ist es keine gute Sache, still zu versagen. Wenn ein Fehler auftritt, funktioniert die App nicht. Stattdessen sollte versucht werden, das Problem zu beheben, oder eine Warnung angezeigt werden, z. B. "Benutzerdaten konnten nicht geladen werden, möglicherweise sind Sie nicht mit dem Internet verbunden?". Wenn die App nicht das tut, was sie tun soll, ist das für einen Benutzer viel frustrierender, als wenn er sich selbst schließt.

(4) Wenn der Benutzer unvollständig ist, z. Das Land ist nicht bekannt und gibt null zurück. Die equals-Methode erstellt eine NullPointerException. Wenn diese NPE wie oben geworfen und abgefangen wird, wird die Methode fillFields (user) nicht aufgerufen, obwohl sie trotzdem problemlos ausgeführt werden konnte. Sie können dies verhindern, indem Sie Nullprüfungen einschließen, die Ausführungsreihenfolge ändern oder den Try/Catch-Bereich anpassen. (Oder Sie können die Codierung wie folgt speichern: "us" .equals (user.getCountry ()), aber ich musste ein Beispiel angeben). Natürlich verhindert jede andere Ausnahme auch die Ausführung von fillFields (), aber wenn es keinen Benutzer gibt, möchten Sie wahrscheinlich, dass es sowieso nicht ausgeführt wird.

(1, 2, 3) Beim Laden aus dem Web werden oft verschiedene Ausnahmen ausgelöst, von der IOException über die Ausnahme HttpMessageNotReadable bis hin zur Rückkehr. Möglicherweise ist der Benutzer nicht mit dem Internet verbunden. Möglicherweise wurde ein Backend-Server geändert oder der Server ist ausgefallen, aber Sie wissen es nicht, da Sie Catch (Exception) verwenden. Sie können sogar mehrere davon so fangen

try{
   User user = loadUserFromWeb(); //throws NoInternetException, ServerNotAvailableException or returns null if user does not exist
   if(user == null) { 
       throw new UserDoesNotExistException(); //there might be better options to solve this, but it highlights how exceptions can be used.
   }
   fillFields(user);
   if("us".equals(user.getCountry()) {
       enableExtraFields();
   }
} catch(NoInternetException e){
    displayWarning("Your internet conneciton is down :(");
} catch(ServerNotAvailableException e){
    displayWarning("Seems like our server is having trouble, try again later.");
} catch(UserDoesNotExistException e){
    startCreateUserActivity();
}

Ich hoffe das erklärt es.

Zumindest als schnelle Lösung könnten Sie ein Ereignis mit der Ausnahme an Ihr Backend senden. Zum Beispiel durch Firebase oder Crashlytics. Auf diese Weise können Sie zumindest Dinge wie (hey, die Hauptaktivität wird für 80% unserer Benutzer aufgrund eines Problems wie (4) nicht geladen) angezeigt.

9
Syzygy

Es ist definitiv eine schlechte Programmierpraxis. 

Wenn im aktuellen Szenario hunderte von trycatch vorhanden sind, wissen Sie nicht einmal, wo die Ausnahme auftritt, ohne die Anwendung zu debuggen. Dies ist ein Albtraum, wenn sich Ihre Anwendung in der Produktionsumgebung befindet.

Sie können jedoch einen Logger hinzufügen, damit Sie wissen, wann eine Ausnahme ausgelöst wird (und warum). Ihr normaler Workflow wird dadurch nicht geändert.

...
try {
    View view = findViewById(R.id.toolbar);
}catch(Exception e){
    logger.log(Level.SEVERE, "an exception was thrown", e);
}
...
8
Raman Sahasi

Das ist eine schlechte Praxis. Andere Antworten haben das gesagt, aber ich denke, es ist wichtig, zurückzutreten und zu verstehen warum wir haben in erster Linie Ausnahmen.

Jede Funktion hat eine Nachbedingung - eine Menge von Dingen, die alle wahr sein müssen, nachdem diese Funktion ausgeführt wurde. Beispielsweise hat eine Funktion, die aus einer Datei liest, die Post-Bedingung, dass die Daten in der Datei von der Festplatte gelesen und zurückgegeben werden. Eine Ausnahme wird dann ausgelöst, wenn eine Funktion eine ihrer Nachbedingungen nicht erfüllen konnte.

Indem Sie eine Ausnahme von einer Funktion ignorieren (oder sie sogar effektiv ignorieren, indem Sie die Ausnahme einfach protokollieren), sagen Sie, dass Sie mit dieser Funktion in Ordnung sind und nicht die gesamte vereinbarte Arbeit ausführen. Dies ist unwahrscheinlich. Wenn eine Funktion nicht ordnungsgemäß ausgeführt wird, kann nicht garantiert werden, dass das Folgende überhaupt ausgeführt wird. Und wenn der Rest Ihres Codes gut läuft, ob eine bestimmte Funktion vollständig ausgeführt wird oder nicht, fragt man sich, warum Sie diese Funktion überhaupt haben.

[Nun gibt es bestimmte Fälle, in denen leere catches in Ordnung sind. Zum Beispiel ist die Protokollierung etwas, das Sie rechtfertigen könnten, wenn Sie einen leeren Fang einwickeln. Ihre Anwendung wird wahrscheinlich einwandfrei ausgeführt, auch wenn ein Teil der Protokollierung nicht geschrieben werden kann. Aber das sind spezielle Fälle, für die man sehr hart arbeiten muss, um sie in einer normalen App zu finden.]

Der springende Punkt ist also, dass dies eine schlechte Praxis ist, da Ihre App dadurch nicht mehr ausgeführt wird (die angebliche Rechtfertigung für diesen Stil). Vielleicht hat das Betriebssystem es technisch nicht gekillt. Es ist jedoch unwahrscheinlich, dass die App nach dem Ignorieren einer Ausnahme weiterhin ordnungsgemäß ausgeführt wird. Und im schlimmsten Fall könnte es tatsächlich Schaden anrichten (z. B. Benutzerdateien beschädigen usw.).

7
JoshG79

Das ist aus mehreren Gründen schlecht:

  1. Was tun Sie, dass findViewById eine Ausnahme auslöst? Reparieren Sie das (und sagen Sie mir, weil ich das noch nie gesehen habe), anstatt es zu fangen.
  2. Fangen Sie nicht Exception, wenn Sie einen bestimmten Ausnahmetyp abfangen könnten. 
  3. Es besteht die Überzeugung, dass gute Apps nicht abstürzen. Das ist nicht wahr. Eine gute App stürzt ab, wenn sie muss.

Wenn eine App in einen schlechten Zustand gerät, ist es viel besser, dass sie abstürzt, als dass sie in ihrem unbrauchbaren Zustand mitschleppt. Wenn man eine NPE sieht, sollte man nicht einfach eine Nullprüfung durchführen und weggehen. Der bessere Ansatz besteht darin, herauszufinden, warum etwas NULL ist, und entweder das NULL zu verhindern oder (wenn NULL ein gültiger und erwarteter Zustand ist), nach NULL zu suchen. Aber Sie müssen verstehen, warum das Problem überhaupt auftritt.

3
A J

Ich habe in den letzten 4-5 Jahren Android-Apps entwickelt und nie einen Try-Catch für die Initialisierung von Ansichten verwendet.

Wenn es eine Symbolleiste ist, mache das so

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

zB: - Um eine TextView aus einer Ansicht zu erhalten (Fragment/Dialog/beliebige benutzerdefinierte Ansicht)

TextView textview = (TextView) view.findViewById(R.id.viewId);

TextView textview = (TextView) view.findViewById (R.id.viewId);

an Stelle von

View view = findViewById(R.id.toolbar);

Ein Ansichtsobjekt hat im Vergleich zum realen Ansichtstyp eine minimale Reichweite.

Hinweis: - Möglicherweise ist es abgestürzt, weil die Ansicht geladen wurde. Das Hinzufügen von Try Catch ist jedoch eine schlechte Praxis. 

2
shijin

Wie bereits erwähnt, sollten allgemeine Ausnahmen nicht oder nur an einer wenigen zentralen Stelle abgefangen werden (normalerweise im Framework-/Infrastrukturcode, nicht im Anwendungscode). Wenn allgemeine Ausnahmen abgefangen und protokolliert werden, sollte die Anwendung anschließend heruntergefahren werden, oder der Benutzer sollte zumindest darüber informiert werden, dass sich die Anwendung möglicherweise in einem instabilen Zustand befindet und dass Datenbeschädigungen auftreten können (falls der Benutzer die Ausführung fortsetzt). Denn dies kann passieren, wenn Sie alle möglichen Ausnahmen abfangen (zu wenig Speicher, um nur eine zu nennen) und die App in einem undefinierten Zustand belassen.

IMHO ist es schlimmer, Ausnahmen zu verschlucken und die Datenintegrität, den Datenverlust oder einfach das Verlassen der App in einem undefinierten Zustand zu riskieren, als die App abstürzen zu lassen und der Benutzer weiß, dass etwas schief gelaufen ist und es erneut versuchen kann. Dies führt auch zu besseren gemeldeten Problemen (mehr an der Wurzel des Problems), wahrscheinlich weniger unterschiedlichen Symptomen, als wenn Ihre Benutzer anfangen, alle Arten von Problemen zu melden, die vom undefinierten Anwendungsstatus herrühren.

Beginnen Sie nach einer zentralen Ausnahmebehandlung/-protokollierung/-berichterstattung und einem kontrollierten Herunterfahren mit dem Umschreiben der Ausnahmebehandlung, um lokale Ausnahmen so spezifisch wie möglich zu erfassen. Versuchen Sie, den try {} -Block so kurz wie möglich zu halten.

1
DavWEB

Lassen Sie mich meinen Standpunkt hinzufügen, als ein Mann, der seit mehr als einem Jahrzehnt in der Unternehmensentwicklung für mobile Entwicklung tätig ist. Zunächst einige allgemeine Tipps zu Ausnahmen, von denen die meisten in den obigen Antworten enthalten sind:

  • Ausnahmen sollten für außergewöhnliche, unerwartete oder unkontrollierte Situationen verwendet werden, nicht regelmäßig im gesamten Code.
  • Ein Programmierer muss die Teile des Codes kennen, die Ausnahmen auslösen können, und sie versuchen, sie zu fangen, wobei der Rest des Codes so sauber wie möglich bleibt.
  • Ausnahmen sollten generell nicht stumm bleiben.

Wenn Sie jetzt keine App für sich selbst, sondern für ein Unternehmen oder ein Unternehmen entwickeln, werden häufig zusätzliche Anforderungen zu diesem Thema gestellt:

  • "App-Abstürze zeigen ein schlechtes Image des Unternehmens und sind daher nicht akzeptabel." Dann sollte eine sorgfältige Entwicklung durchgeführt werden, und es kann eine Option sein, auch unwahrscheinliche Ausnahmen einzufangen. Wenn ja, muss dies selektiv erfolgen und in vernünftigen Grenzen gehalten werden. Beachten Sie, dass es bei der Entwicklung nicht nur um Codezeilen geht. Beispielsweise ist ein intensiver Testprozess in diesen Fällen kritisch. Unerwartetes Verhalten in einer Unternehmensanwendung ist jedoch schlimmer als ein Absturz. Immer wenn Sie eine Ausnahme in Ihrer App feststellen, müssen Sie wissen, was zu tun ist, was angezeigt werden soll und wie sich die App als Nächstes verhalten wird. Wenn Sie das nicht kontrollieren können, lassen Sie die App besser abstürzen.
  • "Protokolle und Stapelverfolgungen können vertrauliche Informationen an die Konsole übertragen. Dies kann für einen Angreifer verwendet werden. Aus Sicherheitsgründen können sie nicht in einer Produktionsumgebung verwendet werden." Diese Anforderung steht im Widerspruch zur allgemeinen Regel, dass ein Entwickler keine stumm geschriebenen Ausnahmen schreiben darf. Daher müssen Sie einen Weg dafür finden. Zum Beispiel könnte Ihre App die Umgebung steuern, so dass sie Protokolle und Stack-Traces in Produktionsumgebungen verwendet und Cloud-basierte Tools wie Bugsense, Crashlitics oder ähnliches für Produktionsumgebungen verwendet.

Die kurze Antwort lautet also, dass der Code, den Sie gefunden haben, kein gutes Beispiel ist, da die Wartung schwierig und kostspielig ist, ohne die Qualität der App zu verbessern.

1
Miguel

Ja, Try/Catch wird verwendet, um den Absturz der App zu verhindern. Sie benötigen Try/Catch jedoch nicht, um eine Ansicht aus XML abzurufen, wie in Ihrer Frage dargestellt.

try/catch wird im Allgemeinen bei jeder HTTP-Anfrage verwendet, beim Analysieren von String-zu-URLs, Erstellen von URL-Verbindungen usw. Stellen Sie außerdem sicher, dass der Stack-Trace gedruckt wird. Wenn Sie nicht drucken, ist es nicht sinnvoll, Try/Catch zu verwenden.

Die Verwendung von catch(Exception e){} ist schlecht, da Sie den Fehler im Wesentlichen ignorieren. Was Sie wahrscheinlich tun möchten, ist etwas mehr:

try {
    //run code that could crash here
} catch (Exception e) {
    System.out.println(e.getMessage());
}
0
chbchb55

Wir verwenden ziemlich genau dieselbe Logik. Verwenden Sie try-catch, um zu verhindern, dass Produktionsanwendungen abstürzen.

Ausnahmen solltenNIEMALSignoriert werden. Es ist eine schlechte Kodierungspraxis. Den Jungs, die den Code verwalten, fällt es schwer, den Teil des Codes zu lokalisieren, der die Ausnahme ausgelöst hat, wenn sie nicht protokolliert werden.

Wir verwenden Crashlytics, um die Ausnahmen zu protokollieren. Der Code stürzt nicht ab (einige Funktionen werden jedoch unterbrochen). Das Ausnahmelog wird jedoch im Dashboard von Fabric/Crashlytics angezeigt. Sie können diese Protokolle anzeigen und die Ausnahmen beheben.

try {
    codeThatCouldRaiseError();
} catch (Exception e) {
    e.printStackTrace();
    Crashlytics.logException(e);
}
0
K Neeraj Lal

Obwohl ich mit den anderen Antworten einverstanden bin, gibt es einen Umstand, bei dem dieses Motiv nur geringfügig tolerierbar ist. Angenommen, jemand hat ein bisschen Code für eine Klasse wie folgt geschrieben:

private int foo=0;

    . . .

public int getFoo() throws SomeException { return foo; }

In diesem Fall kann die Methode 'getFoo ()' nicht fehlschlagen - der legitime Wert des privaten Felds 'foo' wird zurückgegeben. Dennoch entschied jemand - wahrscheinlich aus pedantischen Gründen -, dass diese Methode als potenziell auslösende Ausnahme deklariert werden sollte. Wenn Sie dann versuchen, diese Methode in einem Kontext aufzurufen - z. B. in einem Event-Handler -, bei dem keine Ausnahme ausgelöst werden kann, müssen Sie grundsätzlich dieses Konstrukt verwenden (auch wenn ich damit einverstanden bin, dass Sie dies zumindest tun sollten log die Ausnahme nur für den Fall). Immer wenn ich dies tun muss, füge ich immer einen dicken Kommentar "THIS CANNOT OCCUR" neben der "catch" -Klausel hinzu.

0
PMar