der Quellcode vor dem Kompilieren und Progard:
%Vor%der dekompilierte Code nach dem Kompilieren und Progardieren: (Dekompiliert mit CFR 0_118)
%Vor% ist jetzt der Schlüsselcode nach compile & amp; progard, dem dekompilierten Code der b
-Klasse:
bezog sich immer noch auf die Methode finish()
, die bereits von prouard als m()
verschleiert wurde.
Ich erwarte, dass die referenz finish () -Methode als m () verschleiert wird, aber das passiert nicht, und das ist meine Frage.
Proguard hat mich nicht gewarnt, es stürzt nur mit NoSuchMethodError
auf der Laufzeit ab, sobald es den falschen Code trifft. Also sag mir nicht, dass ich eine Proguard-Konfiguration wie -dontwarn java.lang.invoke. * hinzufügen soll, die ich ausprobiert habe, aber es hat nicht funktioniert.
Vielleicht war die Bearbeitungsreihenfolge der beteiligten Klassen während der Verschleierung falsch, wer weiß?
Ich möchte die Annotation @Keep
nicht in die finish () -Methode einfügen, es ist eine schlechte Lösung und ich müsste mich darum kümmern und Methodenreferenzen in Zukunft sorgfältig verwenden, also suche ich nach der beste Lösung.
unten sind meine Standardkonfigurationen:
%Vor% Unten ist mein proguard-rules.pro
:
Nach einer nochmaligen Überprüfung, habe ich festgestellt, dass es sich wahrscheinlich nicht um einen Programmfehler handelt, sondern nur um Großbuchstaben.
Zuerst lasse ich den Quellcode unter Verwendung des allgemeinen Schnittstellencodierungsstils:
%Vor%Dann reinige ich den Build-Cache und rebuild:
%Vor%Ich führe die Ausgabeversions-App aus und lasse sie den problematischen Code erreichen, der ohne Absturz funktioniert.
Dieses Mal wende ich mich Methodenreferenzen zu:
%Vor%aber ich habe den Build-Cache vor dem erneuten Aufbau nicht bereinigt:
%Vor%jetzt wieder mit dem Absturz passieren geschehen:
%Vor%um zu bestätigen, dass es sich um den Build-Cache-Grund handelt, baue ich den grundlegend auf den geänderten Code zurück:
%Vor%Dieser Absturz ist in der Nachwort-App verschwunden.
Ich versuche, ein Demonstrationsprojekt zu erstellen, um dieses Problem zu beweisen, aber das Projekt stürzt den Absturz nur in meinem produktiven Projekt ab.
Das Durcharbeiten dieser Fehler, die -keep
nicht beheben kann, ist ein REAL Schmerz und der einzige Weg, auf dem ich je Fortschritte gemacht habe, ist die folgende Strategie:
E.G.
Stellen Sie sicher, dass dies ein Optimierungsproblem ist oder nicht
-dontoptimize
anstelle von -optimizations
string rebuild und test !method/*, !code/*, !class/*, !field/*
, bis Sie feststellen, durch welchen Ausschluss das Problem behoben wird !method/*
, gehen Sie von !method/marking/*
und wenn das auch funktioniert, versuchen Sie !method/marking/final
. Wenn das funktioniert, dann haben Sie die gefunden minimaler Ausschluss) Dies könnte sehr wohl ein Fehler in den Proguard Regeln einer der verwendeten Bibliotheken sein oder in der Version von Proguard, die Sie selbst verwenden (I hab beide gesehen also versuche beide auch zu aktualisieren.
Die Webseite / github Ihrer Bibliothek bietet meistens die notwendigen Regeln für die Progardierung wie retrolamda :
%Vor%Proguarding ist eine Trail-Error-Geschichte. Überprüfen Sie Ihre Protokollierung, um festzustellen, welche Bibliothek, Klasse oder Komponente ein Problem verursacht, und fügen Sie sie sorgfältig zu den Regeln hinzu:).
Ihr Fehler NoSuchMethod speziell:
Ihr Code ruft wahrscheinlich etwas wie myClass.getMethod auf und versucht es um eine Methode dynamisch zu finden. Da ProGuard nicht immer erkennen kann Dies müssen Sie automatisch die fehlende Methode bei der Verwendung der geeignete Option -keep:
-keepclassmembers-Klasse mypackage.MyClass {void myMethod (); }
Dies geschieht, wenn eine Klasse nach einer Methode eines gegebenen Arguments sucht oder sie direkt über die Reflektion zur Laufzeit aufruft. Proguard kann Sie dazu nicht warnen, da in der Kompilierzeit keine Verbindung zwischen der verschleierten Klasse und der Verbraucherklasse besteht. Du kannst etwas wie
haben %Vor%Da die Methode referenziert wird, wird eine Zeichenkette mit dem Namen verwendet, proguard erkennt sie nicht und in der Laufzeit kommt es zu einem Absturz. Die einzige Lösung ist, vorausgesetzt, Sie können den Code nicht ändern, ist es, die Methode und Klasse zu verschleiern.
(Sie können ein realistischeres Beispiel in Ormlite-Android überprüfen)
Tags und Links android gradle android-proguard