根据谷歌,我必须在发布我的Android应用程序谷歌播放之前“停用源代码中的Log方法的任何调用”。出版清单第3节节选:
在构建应用程序发布之前,请确保禁用了日志记录并禁用了调试选项。您可以通过删除源文件中对Log方法的调用来禁用日志记录。
我的开源项目很大,每次发布都要手动完成,这很痛苦。此外,删除Log行可能很棘手,例如:
if(condition)
Log.d(LOG_TAG, "Something");
data.load();
data.show();
如果注释Log行,则该条件将应用于下一行,并且可能不会调用load()。这样的情况是否罕见到我可以决定它不应该存在?
那么,是否有更好的源代码级方法来做到这一点呢?或者是一些聪明的ProGuard语法,有效但安全地删除所有Log行?
我在我的项目中使用了以下方法
创建自定义记录器类:
public class LoggerData
{
public static void showLog(String type, Object object) {
try {
Log.d("loggerData:" + type + "-", "showLog: " + new Gson().toJson(object));
} catch (Exception e) {
Log.d("TAG", "showLog: " + e.getLocalizedMessage());
Log.d("loggerData:" + type + "-", "showLog: " + object);
}
}
public static void showLog(Object object) {
try {
Log.d("loggerData:" + "-", "showLog: +" + new Gson().toJson(object));
} catch (Exception e) {
Log.d("TAG", "showLog: " + e.getLocalizedMessage());
Log.d("loggerData:" + "-", "showLog: " + object);
}
}
}
然后每当需要登录代码时,就像这样使用
LoggerData.showLog("Refreshed token: ", token);
在构建发布APK之前,在LoggerData类中只禁用一个地方的日志
例子
public class LoggerData {
public static void showLog(String type, Object object) {
try {
//Log.d("loggerData:" + type + "-", "showLog: " + new Gson().toJson(object));
} catch (Exception e) {
//Log.d("TAG", "showLog: " + e.getLocalizedMessage());
//Log.d("loggerData:" + type + "-", "showLog: " + object);
}
}
public static void showLog(Object object) {
try {
// Log.d("loggerData:" + "-", "showLog: +" + new Gson().toJson(object));
} catch (Exception e) {
//Log.d("TAG", "showLog: " + e.getLocalizedMessage());
//Log.d("loggerData:" + "-", "showLog: " + object);
}
}
}
希望它也能帮助到你。
如果您希望使用编程方法而不是使用ProGuard,那么通过创建自己的类,其中包含两个实例(一个用于调试,一个用于发布),您可以选择在任何一种情况下登录什么。
所以,如果你不想在发布时记录任何东西,只需实现一个什么都不做的Logger,如下例所示:
import android.util.Log
sealed class Logger(defaultTag: String? = null) {
protected val defaultTag: String = defaultTag ?: "[APP-DEBUG]"
abstract fun log(string: String, tag: String = defaultTag)
object LoggerDebug : Logger() {
override fun log(string: String, tag: String) {
Log.d(tag, string)
}
}
object LoggerRelease : Logger() {
override fun log(string: String, tag: String) {}
}
companion object {
private val isDebugConfig = BuildConfig.DEBUG
val instance: Logger by lazy {
if(isDebugConfig)
LoggerDebug
else
LoggerRelease
}
}
}
然后使用记录器类:
class MainActivity : AppCompatActivity() {
private val logger = Logger.instance
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
logger.log("Activity launched...")
...
myView.setOnClickListener {
...
logger.log("My View clicked!", "View-click")
}
}
== update ==
如果我们想避免字符串连接以获得更好的性能,我们可以添加一个带有lambda的内联函数,该函数只在调试配置中调用:
// Add this function to the Logger class.
inline fun commit(block: Logger.() -> Unit) {
if(this is LoggerDebug)
block.invoke(this)
}
然后:
logger.commit {
log("Logging without $myVar waste of resources"+ "My fancy concat")
}
因为我们使用的是内联函数,所以没有额外的对象分配,也没有额外的虚方法调用。
打开“Application->app->proguard-rules.pro”
在proguard-rules.pro '中输入以下代码
android.util.Log {
公共静态*** d(…);
公共静态*** v(…);
公共静态*** w(…);
公共静态*** i(…);
公共静态*** e(…);
}
#你可以删除特定的调试类,如果你想在日志中的调试类型错误
In build.gradle(app) ->android do this thing
buildTypes {
debug{
debuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-
optimize.txt'), 'proguard-rules.pro'
}
release {
debuggable false
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-
optimize.txt'), 'proguard-rules.pro'
}
}
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}