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

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

原理:

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

通过配置proguard,将类android.util.Log的方法给置为为无效代码,然后在导出的apk里就是被删除掉日志的。(proguard是一个代码优化的工具,也可以混淆代码)

如何关闭日志:

我的项目目录:
 

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 <fields>;

}

-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的日志。

assumenosideeffects

assumenosideeffects,proguard 配置文件里的参数。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)

检验是否真的能优化掉日志。。
  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. Log.e("MainActivity", "log" );
  7. }
  8. }

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

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

运行LogCat中没有输出日志。

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

源码2)

Log.e("jiese1990", test() );test()函数会被一起优化掉吗?
  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. Log.e("MainActivity", "log " + test());
  7. }
  8. private String test(){
  9. Toast.makeText(this, "test", Toast.LENGTH_SHORT).show();
  10. return "jjyy";
  11. }
  12. }

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

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

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

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

源码3):

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

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

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

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

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

android关闭日志的更多相关文章

  1. 大叔也说Xamarin~Android篇~日志的记录

    回到目录 无论哪个平台,开始哪种应用程序,日志总是少不了的,大家在Lind.DDD里也可以看到大叔的日志组件,而在xamarin进行移动开发时,为了更好的调试,记录运行的情况,日志也是必须的,这讲主要 ...

  2. [原创]adb使用教程v1.0-----by-----使用logcat快速抓取android崩溃日志

    原文再续,书接上回:<使用logcat快速抓取android崩溃日志>中提到的工具包可以下载拉~ <使用logcat快速抓取android崩溃日志>:http://www.cn ...

  3. [原创]adb使用教程v1.1.0-----by-----使用logcat快速抓取android崩溃日志

    原文再续,书接上回:<使用logcat快速抓取android崩溃日志>中提到的工具包可以下载拉~ <使用logcat快速抓取android崩溃日志>:http://www.cn ...

  4. RMS Server打开或关闭日志记录

    原文: https://technet.microsoft.com/zh-cn/library/cc732758 在 Active Directory Rights Management Servic ...

  5. 开启win7系统关闭日志分析

    笔记本突然没有任何征兆的自动重启了,想起之前曾经在网上看过通过系统日志查看一下是哪个东东搞的鬼,于是开始上网搜索,发现默认情况下是关机的信息记录的很少,不过可以开启审计功能来记录这个捣鬼的程序.于是就 ...

  6. 使用Monitor调试Unity3D Android程序日志输出(非DDMS和ADB)

    使用Monitor调试Unity3D Android程序日志输出(非DDMS和ADB) http://www.cnblogs.com/mrkelly/p/4015245.html 以往调试Androi ...

  7. Android Studio日志工具的使用

    Android Studio的LogCat工具 Verbose:对应Log.v(),这个方法用于打印那些最为琐碎的信息,意义最小的日志信息.是Android日志里面级别最低的一种. Debug:对应L ...

  8. wordpress数据库优化-关闭日志修订

    每次在wordpress网站修改文章的时候都会产生一个修订版本,wp_posts会产生一个post_type为“REVISIONS”的记录,修改次数一多的话,那修订版本就有几万条记录了 在functi ...

  9. ZENCART 打开/关闭日志文件

    优秀的php开源程序很多都只带生成日志文件的功能,这类功能的开发可以帮助到站长在调试网站的时候及时的改正网站存在的错误,但是这类错误日志由来并非网站出现什么严重不可挽救的错误,大部分是一些未定义变量这 ...

随机推荐

  1. maven 通过 pom.xml 指定java编译版本

    <!-- 给maven项目指定编译版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> ...

  2. windows下docker启动.net core mvc随手记

    docker基本命令: 查看当前的版本docker--version查看本地所有镜像:docker images查看当前正在运行的所有容器docker ps停止某个容器:docker stop 容器I ...

  3. 类似于PLC上升沿的TRIO代码示例

    需求:    一个自复位按钮,控制灯泡的亮与灭(按钮按一次灯亮,再按一次灯灭依次循环). 简短的代码,若大家有更好的思路可以评论区留言. DIM in_button,op_lamp,var_middl ...

  4. os模块 与 sys模块

    os模块 os模块是与操作系统交互的一个接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工 ...

  5. C. Ehab and a 2-operation task

    链接 [https://codeforces.com/contest/1088/problem/C] 题意 n个数,最多n+1操作,要么前i个数加x,要么前i个数对x取余,最后使得严格递增 分析 直接 ...

  6. 【ML】ICLR2016_Delving Deeper into Convolutional Networks

    ICLR2016_DELVING DEEPER INTO CONVOLUTIONAL NETWORKS Note here: Ballas recently proposed a novel fram ...

  7. 实践——ELF文件格式分析

    一.分析文件头 1. 段入口类型定义(/usr/include/elf.h)下面产生的hello是32位的 使用命令#Hexdump –x ELF_1.o 第一行: 前4字节,蓝色部分,是一个魔数,表 ...

  8. jeecg的下拉列表

    jeecg里面下拉列表的使用 ①建立数据字典seo_id <t:dictSelect field="operationPromotionAccount" typeGroupC ...

  9. Doors Breaking and Repairing CodeForces - 1102C (思维)

    You are policeman and you are playing a game with Slavik. The game is turn-based and each turn consi ...

  10. AAPT2 error: check logs for details 问题的终究修复

    AAPT2 error: check logs for details Process 'command '***\build-tools\27.0.3\aapt.exe'' finished wit ...