我们在开发时,经常会输出各种日志来debug代码。但是等到应用发布的apk运行时不希望它输出日志。

关闭输出日志Log.v(),Log.i(),Log.w(),Log.v(),Log.e()等

原理:

那么我们可以通过proguard来删除各种日志输出代码。然后导出apk时,将会过滤掉日志代码。

通过配置proguard,将类android.util.Log的方法给置为为无效代码。(proguard是一个代码优化的工具,也可以混淆代码)

assumenosideeffects

assumenosideeffects,assume no side effects;假定无效;该属性也就是标识无效代码。我们就是通过这个参数来让proguard删除日志代码。

assumenosideeffects的官方解释:

In the optimization step, ProGuard will then remove calls to such methods, if it can determine that the return values aren't used.ProGuard will analyze your program code to find such methods automatically.It will not analyze library code, for which this option can therefore be useful.

In general, making assumptions can be dangerous; you can easily break the processed code. Only use this option if you know what you're doing!

如下:

-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}

使用这个配置时,一定要注意-dontoptimize,配置。

don‘t optimize 不要优化;将会会关闭优化,导致日志语句不会被优化掉。所以不能有这个配置

如何关闭日志:

我的项目目录:

1)打开proguard-------修改project.properties文件。

在project.properties文件最后行添加:proguard.config=proguard

如我的project.properties文件:

target=android-18

proguard.config=proguard-project.txt

2)配置proguard-------修改proguard配置文件,

如:我的配置文件是:proguard-project.txt

配置为:

-keepclassmembers class * extends android.app.Activity {

public void *(android.view.View);

}

-keep class * implements android.os.Parcelable {

public static final android.os.Parcelable$Creator *;

}

-dontwarn android.support.**

-keepclassmembers class **.R$* {

public static ;

}

-assumenosideeffects class android.util.Log {

public static boolean isLoggable(java.lang.String,int);

public static int v(...);

public static int i(...);

public static int w(...);

public static int d(...);

public static int e(...);

}

3)导出关闭日志的apk

proguard,在导出apk的时候才会优化代码,生成优化后的apk。(完成代码混淆也是在导出apk,proguard将代码混淆后生成apk)

通过如上两个步骤,配置project.properties文件和proguard.properties文件;那么项目就配置好了。可以直接导出签名apk,该apk不会输出日志,我们用LogCat是看不到该apk的日志。

测试

源码1)

1
2
3
4
5
6
7
8
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("MainActivity", "log" );
    }
}

通过生成的apk反编译出如下代码1-1)

1
2
3
4
5
6
7
8
public class MainActivity extends Activity
{
  protected void onCreate(Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    setContentView(2130903040);
  }
}

运行LogCat中没有输出日志。

很明显Log.e("MainActivity","log" );被优化掉了

源码2)

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("MainActivity", "log " + test());
    }
     
    private String test(){
        Toast.makeText(this, "test", Toast.LENGTH_SHORT).show();
        return "jjyy";
    }
}

通过生成的apk反编译出如下代码2-1)

1
2
3
4
5
6
7
8
9
10
11
12
public class MainActivity extends Activity
{
  protected void onCreate(Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    setContentView(2130903040);
    //如下是test()函数的代码
    StringBuilder localStringBuilder = new StringBuilder("log ");
    Toast.makeText(this, "test", 0).show();
    localStringBuilder.append("jjyy").toString();
  }
}

运行LogCat中没有输出日志。但是弹出toast。

很明显Log.e();被优化掉了,但是test()方法依然被保留了,

源码3):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MainActivity extends Activity {
    int i = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.e("MainActivity", "log" + test() );
        Toast.makeText(this, "i = " + i, Toast.LENGTH_SHORT).show();    //i == 1;
    }
 
    private String test(){
        i++;
        return "test" + i;
    }
}

通过生成的apk反编译出如下代码3-1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MainActivity extends Activity
{
  private int a = 0;    //proguard将代码混淆后变量i变为了a
 
  protected void onCreate(Bundle paramBundle)
  {
    super.onCreate(paramBundle);
    setContentView(2130903040);
    //Log.e()代码被删除了,但是调用test()函数里的i++被直接优化到这里
    StringBuilder localStringBuilder = new StringBuilder("log");   
    this.a = (1 + this.a);
    localStringBuilder.append("test" + this.a).toString();
    Toast.makeText(this, "i = " + this.a, 0).show();
  }
}

运行LogCat中没有输出日志。但是弹出toast 显示字符串 : "i = 1"

很明显Log.e();被优化掉了,但是test()方法依然被保留了,

Eclipse 打包过滤 Log.e的更多相关文章

  1. eclipse打包apk

    eclipse打包apk

  2. tar打包过滤某个文件及文件夹

    ip=ip add|grep eth0|grep -i inet|awk '{print $2}'|cut -d '/' -f 1 cd /data tar -zvcf `echo $ip`_`dat ...

  3. Eclipse打包出错——提示GC overhead limit exceeded

    版权声明:本文为博主原创文章,未经博主允许不得转载. 在Eclipse开发环境中打包发布apk安装包的时候,有时候会出现下面的错误: 原因 在打包的时候,Eclipse占用的内存会增大,当分配给Ecl ...

  4. Eclipse打包Egret App (Egret4.1.0)

    Egret官方提供eclipse和androidstudio打包. 这里使用eclipse. 1 下载配置android环境 2 Egret打包App 3 Eclipse设置 4 Eclipse调试 ...

  5. eclipse启动报错:An error has occurred.See the log file D:\eclipse\configuration\1552616709202.log

    如题,Eclipse崩了,只能按它留下的线索去看了1552616709202.log: !SESSION -- ::08.739 ----------------------------------- ...

  6. Eclipse打包java工程

    Eclipse打包java工程步骤如下: 1.选择预打包的工程->Export. 2.选择java->JAR file. 3.导出JAR文件设置. 这里有几个选项: Export gene ...

  7. eclipse打包插件net.sf.fjep.fatjar

    eclipse打包插件安装 1)将net.sf.fjep.fatjar_0.0.32.jar拷贝到eclipse安装目录中的plugins目录下,然后重启eclipse即可. 软件获取方式: 链接:h ...

  8. vue webpack build 打包过滤console.log()日志

    vue cli创建项目在 webpack.prod.conf.js文件 //打包时清除页面中所有打印及debugger断点 new webpack.optimize.UglifyJsPlugin({ ...

  9. webpack打包过滤console.log

    在webpack.prod.conf.js里面的plugins里面加上 drop_debugger: true, drop_console: true new webpack.optimize.Ugl ...

随机推荐

  1. 让rdlc报表在ReportViewer中水平居中的方法

    正常情况下,rdlc报表在Reportviewer中是居左显示的,如图: 在Reporviewer的属性中,我没有找到能让rdlc的居中显示的方法.网上其他人用的方法都试了,没能实现,只能自己找方法解 ...

  2. UVA 10570 Meeting with Aliens

    题意: N个外星人围成一桌坐下,有序的排列指N在N-1与N+1中间,现在给出一个序列,问至少交换几次可以得到有序的序列. 分析: 复制一遍输入序列,放在原序列之后.相当于环.通过枚举,可以把最小交换次 ...

  3. char varchar varchar2 的区别 (转)

    char varchar varchar2 的区别       http://blog.csdn.net/honglei_zh/article/details/7172538区别:1.CHAR的长度是 ...

  4. 【noip2012提高组】国王游戏

    恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍的最前面. ...

  5. EC读书笔记系列之20:条款53、54、55

    条款53 不要轻忽编译器的警告 记住: ★严肃对待编译器发出的警告信息.努力在你的编译器的最高(最严苛)警告级别下争取“无任何警告”的荣誉 ★不要过度依赖编译器的报警能力,∵不同的编译器对待事情的态度 ...

  6. mysql学习(八)数据表类型-字符集

    数据存储引擎: MyISAM:强化快速读取操作. 也有缺点.一些功能不支持 InnoDB:支持一些MyIASM一些不支持的功能                 缺点:占用空间大 对比          ...

  7. 在Windows的Wamp环境下安装Composer

    注意: PHP缺少openssl扩展. 你可能会去屏幕右下角的Wamp的控制台,去加载php的openssl扩展,或者在php.ini中去掉 extension=php_openssl.dll 这一行 ...

  8. SQLServer 2008 R2 清空日志文件

    USE [master]GOALTER DATABASE FH2_SJH SET RECOVERY SIMPLE WITH NO_WAITGOALTER DATABASE FH2_SJH SET RE ...

  9. 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )

    变量:  存储数据的容器     1.声明        var   2.作用域       全局变量. 局部变量. 闭包(相对的全局变量):   3.类型         a.基本类型(undefi ...

  10. 远程连接mysql数据慢的问题

    由于公司没有服务器,买的阿里云的服务器用于开发,所以就在本地连接服务器的mysql. 连接很慢,打开表也很慢,一开始没多想,以为是网络慢而已. 最近,开发经常要使用navicat连接数据库,实在是太慢 ...