删除记录使用ProGuard不删除被记录的字符串 [英] Removing logging with ProGuard doesn't remove the strings being logged

查看:190
本文介绍了删除记录使用ProGuard不删除被记录的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
  <一href="http://stackoverflow.com/questions/6009078/removing-unused-strings-during-proguard-optimisation">Removing在ProGuard的优化使用的字符串

我有一个Android应用程序与几十个记录的语句。我想preFER他们将不会出现在发布版本,所以我用Proguard的像这样的 proguard.cfg 文件:

I have an Android application with dozens of logging statements. I'd prefer they wouldn't appear in the release version, so I used Proguard with something like this in the proguard.cfg file:

-assumenosideeffects class android.util.Log {
    public static *** d(...);
}

但问题是,有很多的 Log.d(东西+什么的),虽然 Log.d ()语句从字节code被删除,的弦仍然存在

But the problem is that there are a lot of Log.d("something is " + something), and although the Log.d() statement is being removed from the bytecode, the strings are still there.

所以,下面的<一个href="http://stackoverflow.com/questions/6009078/removing-unused-strings-during-proguard-optimisation/6023505#6023505">this答案,我创建了一个简单的包装类,沿着线的东西:

So, following this answer, I created a simple wrapper class, something along the lines of:

public class MyLogger {
    public static void d(Object... msgs) {
        StringBuilder log = new StringBuilder();
        for(Object msg : msgs) {
            log.append(msg.toString());
        }
        Log.d(TAG, log.toString());
    }
}

然后我编辑我的 proguard.cfg

-assumenosideeffects class my.package.MyLogger {
    public static *** d(...);
}

但是字符串中生成的字节code还是发现了!

除了这个,我现在用的是标准的 proguard.cfg 由Android SDK中提供。难道我做错了什么?

Other than this, I am using the standard proguard.cfg provided by the Android SDK. Am I doing something wrong?

修改:检查生成的字节code后,我看到了弦在那里,但他们没有被追加另一个人,因为我以为。他们被存储阵列中的。为什么?为了将它们作为变量参数,我的方法。它看起来像ProGuard的不喜欢,所以我修改这样我的记录器类:

Edit: after examining the generated bytecode, I saw that the strings were there, but they were not being appended one to another, as I thought. They were being stored in an array. Why? To pass them as variable parameters to my method. It looks like ProGuard doesn't like that, so I modified my logger class like this:

public static void d(Object a) {
    log(a);
}

public static void d(Object a, Object b) {
    log(a, b);
}

(... I had to put like seven d() methods ...)

private static void log(Object... msgs) {
    (same as before)
}

这是丑陋的,但现在的字符串是无处字节中code。

这是某种形式的ProGuard的臭虫/限制吗?或者是它只是我不理解它是如何工作?

Is this some kind of bug/limitation of ProGuard? Or is it just me not understanding how it works?

推荐答案

用不同的方法对不同数量的参数你的解决方案可能是最方便的。带有可变数量的参数一个方法会更好,但ProGuard的当前版本是不是足够聪明,删除所有未使用的code。

Your solution with different methods for different numbers of arguments is probably the most convenient one. A single method with a variable number of arguments would be nicer, but the current version of ProGuard is not smart enough to remove all the unused code.

Java编译器编译可变数量的参数作为一个数组参数。在调用方,这意味着创建合适大小的数组,填写的内容,并将它传递给方法。 ProGuard的看到,该阵列被用来在其中存储元件被创建,然后。它不实现(还),它则不能用于实际有用的操作,用方法调用之中去。其结果是,数组创建和初始化preserved。

The java compiler compiles a variable number of arguments as a single array argument. On the invocation side, this means creating an array of the right size, filling out the elements, and passing it to the method. ProGuard sees that the array is being created and then being used to store elements in it. It doesn't realize (yet) that it then isn't used for actual useful operations, with the method invocation being gone. As a result, the array creation and initialization are preserved.

这是一个很好的做法,检查处理code,如果你期待一些特别的优化。

It's a good practice to check the processed code if you're expecting some particular optimization.

这篇关于删除记录使用ProGuard不删除被记录的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆