2012-10-31 9 views
5

Allgemeine Annahmen

So fand ich eine Menge über Progress verwenden, um Protokollanweisungen aus Code zu entfernen. Im Grunde würden alle sagen -assumenosideeffects zusammen mit der Verwendung der $ {sdk.dir} /tools/proguard/proguard-android-optimize.txt-Konfiguration den Trick machen. Mein Verständnis war Bytecode zu erhalten, die zu tun einigeWie man android.Log.d auszieht?

if(Consts.DEBUG) Log.d("",""); 

gleich ist auch bekannt als ich den Anruf zu doSomeExpensiveStuff() von meinem apk eliminiert erhalten angenommen:

android.util.Log.d("Hello","World"+(new Foo().doSomeExpensiveStuff())); 

My-Code

public class MainActivity extends Activity { 
    private class Slooow { 
     @Override 
     public String toString() { 
      // being slow 
      try { 
       Thread.sleep(5000); 
      } catch(InterruptedException e) { 
      } 
      return "bla"; 
     } 
    } 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Log.d("tag", "onCreate: " + (new Slooow().toString())); 
    } 
} 

proguard-project.txt:

-repackageclasses '' 
-optimizationpasses 5 
-dontobfuscate 
-assumenosideeffects class android.util.Log { public * ; } 

dekompilierten dex Datei

.method public onCreate(Landroid/os/Bundle;)V 
.limit registers 5 
; this: v3 (Lcom/example/test/MainActivity;) 
; parameter[0] : v4 (Landroid/os/Bundle;) 
.line 18 
    invoke-super {v3,v4},android/app/Activity/onCreate ; onCreate(Landroid/os/Bundle;)V 
.line 19 
    const/high16 v0,32515 
    invoke-virtual {v3,v0},com/example/test/MainActivity/setContentView ; setContentView(I)V 
.line 20 
    new-instance v0,java/lang/StringBuilder 
    const-string v1,"onCreate: " 
    invoke-direct {v0,v1},java/lang/StringBuilder/<init> ; <init>(Ljava/lang/String;)V 
    new-instance v1,com/example/test/MainActivity$Slooow 
    const/4 v2,0 
    invoke-direct {v1,v2},com/example/test/MainActivity$Slooow/<init> ; <init>(B)V 
    invoke-virtual {v1},com/example/test/MainActivity$Slooow/toString ; toString()Ljava/lang/String; 
    move-result-object v1 
    invoke-virtual {v0,v1},java/lang/StringBuilder/append ; append(Ljava/lang/String;)Ljava/lang/StringBuilder; 
.line 21 
    return-void 
.end method 

Problem

Nun, wenn ich das mein Gerät bereitstellen, ich den 5s Schlaf keine Protokollausgabe erhalten, aber immer noch (oder irgendeine andere Verzögerung oder Absturz von Code, shouldn‘ t störe meine Benutzer). Was mache ich falsch?

Weitere Untersuchungen

Log.d("t", "h" + "w");       // would get stripped just fine. 
if(DEBUG) 
    Log.d("t", "h: " + (new Slooow().toString())); // would get optimized away, too. 
Log.d("t", "h" + bundle.toString());    // has just the same problem as described above. 
+0

gleiches Problem Anwendung abgestürzt, als ich die apk, die durch 'ant release'-Befehl verschleiert ist verwendet – juned

+0

@juned diese Frage hat nichts zu tun mit einem Anwendungsabsturz;) – JesusFreke

Antwort

0

Während ich die Antwort nicht weiß, wie ich glaube, dass final static boolean DEBUG = false mit

hält noch
+0

Danke Alex für die schnelle Antwort. Leider ist dieser "Overhead" nicht erwünscht, obwohl es die einzige Problemumgehung abgesehen von hässlichem Sed-Scripting ist, die ich vorläufig finden könnte. (Ich möchte auch verstehen, warum Proguard überhaupt interessiert, wenn ich eine konstante Zeichenfolge oder eine virtuelle Box in einem Log (,) -Aufruf, wenn es ausdrücklich gesagt wird, dass es keine Nebenwirkungen haben soll.) – Giszmo

+0

Ah , Ich dachte, du wolltest nur die Logcat-Ausgabe strippen, sorry –

1

Es ist wie proguard sieht durch den Compiler vollständig entkleidet in if(D) { Log.d(...) } führen wird, um die Schaffung von die neue Slooow Instanz zu sein/haben eine Nebenwirkung. Auf der Bytecode-Ebene, auf der proguard arbeitet, gibt es im wesentlichen keinen Unterschied zwischen:

Log.d("tag", "onCreate: " + (new Slooow().toString())); 

und

String temp = new Sloooow().toString(); 
Log.d("tag", "onCreate: " + temp); 

So proguard sieht die Log.d und Streifen, die aus, aber es ist Strippen nicht die Schaffung die neue Sloooow Instanz, weil es nicht gesagt wurde, dass das keine Nebenwirkungen hat.

Ich kann mir keine gute Möglichkeit vorstellen, die Erstellung von Sloooow() generisch zu strippen, ohne dem Proguard zu sagen, dass es keine Nebenwirkung hat. (Ich weiß nicht, ob das für einen Konstruktor überhaupt möglich ist)

+0

Klingt plausibel.Ich brauche etwas Schlaf und hoffe auf eine etwas vielversprechendere Antwort, die mein Problem tatsächlich sicher löst, aber irgendwie fühle ich mich, als ob es wenig hinzuzufügen wäre, angesichts meiner proguardzentrischen Frage :) – Giszmo

+0

Das stimmt. ProGuard weiß nicht, dass der Konstruktor und die toString-Methode keine Nebenwirkungen haben. Explizit zu sagen, dass ProGuard unerwünschte Auswirkungen hat, da es (derzeit) beispielsweise für alle toString() - Implementierungen gelten würde. Und die StringBuilder-Methoden haben Nebenwirkungen, obwohl sie nur intern sind. Mögliche Lösung: Wenn Sie Ihre eigene Protokollierungsmethode erstellen können, die den gesamten zusätzlichen Code enthält, können Sie -assumenosideEffects darauf festlegen. –