Android -- Log日志调试(android.utl.log类)

本文介绍如何使用Android.util.log类进行日志记录,包括日志实现原理、不同日志级别的用法及如何在程序中封装日志信息以提高调试效率。通过合理配置日志级别和使用自定义日志构建函数,开发者可以更精确地定位问题并优化代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        Android调试要通过模拟器运行,或者直接USB远程连接到一部手机调试。即使在不关闭模拟进行调试时候,也要经过编译、apk打包、上传apk、运行apk的过程,时间也不短,所以应该在程序固定一次运行中,产生更多我们需要关注的信息,来更清楚的了解程序的运行和逻辑,以便减少上述较长的过程(以前开发用过最土的做法,为了check某个变量的值,使用Toast.makeText()然后show出来,很麻烦)。

        做过互联网后台系统服务或大型程序的人们都知道,如果后台服务异常了,第一反应就是去查日志,看看到底哪里出了问题(提示一下,许多人认为打日志是磁盘操作很影响性能,其实不然,Linux的文件系统会对read/write等系统调用做page cache缓存,只要不是Direct I/O方式基本都可以认为是内存操作),Android系统亦是如此(不过是在调试时候,发布时候则不会带日志)。

        今天要提到的就是Android为我们提供的android.util.log类,可以边运行边打日志,打出的日志可以通过Eclipse的View的LogCat来查询。

        * Android日志实现原理(不关心细节实现可以跳过) :

     首先用户态的App经过Java VM(Android是dalvikvm)产生LOG信息,并与ADB Device Daemon(手机端的adb进程,打开”手机调试“功能时启动的,这就是为什么安装豌豆荚时候手机要开启"手机调试"功能)交互输出这些信息,而ADB Device Daemon又通过相应的协议通过USB(Device)或本地连接(Emulator),与PC上运行的ADB Host Daemon交互,通过PC上的调试工具传递给Eclipse中的ADK插件进行显示。

     具体流程 : 

        App通过util.log.<x>产生日志->JVM->JNI(Native C)调用->log_write的sys_call()->logger驱动->dispatch分发给订阅者

        logger是android系统级的驱动程序,会把注册在系统里的读log的请求者(例如链接过来的eclipse和adb进程、或者linux命令行工具logcat),通过IO复用函数select()来推送数据。

        

        打印日志语句实例 :

Log.v("MyTag", "This is Verbose.");		// 输出verbose级别的字符串

        

        java.util.log里定义了不同级别的输出,分别在LogCat里显示不同的颜色,以便更精准的查找:


Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思,平时使用就是Log.v("","");

Log.d的输出颜色是蓝色的,仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DDMS的Logcat标签来选择.

Log.i的输出为绿色,一般提示性的消息information,它不会输出Log.v和Log.d的信息,但会显示i、w和e的信息

Log.w的意思为橙色,可以看作为warning警告,一般需要我们注意优化Android代码,同时选择它后还会输出Log.e的信息。

Log.e为红色,可以想到error错误,这里仅显示红色的错误信息,这些错误就需要我们认真的分析,查看栈的信息了。


        写程序的时候可以通过调用不同的Log.<x>来分级自己的输出。


        

        打印日志的时候,可能我们不只需要错误的msg,还希望得到调用者的堆栈(比如打log的函数名是什么,类名是什么)。所以,本人编写了一个可以封装这些信息的build函数来封装一些具体信息,用户只需要传入msg即可。并且通过debug开关,在程序发布时候关闭无用的日志调用:

	public static class LogMsgBuidler
	{

		private static boolean DEBUG = true; /* 默认开启 */

		public static void reverse()
		{
			DEBUG = !DEBUG; /* 反转DEBUG设置 */
		}

		public static String build(String msg)
		{

			if (!DEBUG)
				return msg;
			// 获取堆栈信息
			StackTraceElement caller = new Throwable().fillInStackTrace().getStackTrace()[2];

			return new StringBuilder().append(caller.getClassName())
				.append(".").
				append(caller.getMethodName())
				.append("(): ")
				.append(msg).toString();
		}
	}


### ORA-06512错误在使用sqlplus执行脚本时的解决方法及与SYS.UTL_FILE相关的日志文件保存位置 ORA-06512错误通常与PL/SQL程序中的堆栈跟踪信息相关,表示错误发生的程序单元和行号。当使用 `SYS.UTL_FILE` 包进行文件操作时,如果发生错误(如目录权限问题、文件路径不存在、文件无法写入等),ORA-06512会指示错误的具体位置。这种错误本身不会提供具体的文件操作失败原因,因此需要结合其他错误信息(如ORA-29283、ORA-29285等)进行分析。 在使用 `sqlplus` 执行脚本时,若调用了 `SYS.UTL_FILE` 包进行日志写入,日志文件的保存位置由 `UTL_FILE_DIR` 参数或 Oracle 目录对象(`CREATE OR REPLACE DIRECTORY`)定义。通常情况下,这些日志文件存储在数据库服务器的文件系统中,路径由数据库管理员指定。例如: ```sql CREATE OR REPLACE DIRECTORY log_dir AS '/u01/app/oracle/logs'; ``` 在 PL/SQL 代码中使用 `UTL_FILE.FOPEN('LOG_DIR', 'my_log_file.log', 'w')` 打开文件时,日志文件将被写入 `/u01/app/oracle/logs` 目录下。确保该目录存在且 Oracle 用户具有读写权限是避免 ORA-29283 和 ORA-06512 错误的关键条件之一。 处理 ORA-06512 错误时,应首先检查以下方面: - **文件路径是否存在**:确认 `UTL_FILE_DIR` 或目录对象指向的路径在数据库服务器上真实存在。 - **权限设置是否正确**:确保 Oracle 用户对目标目录具有读写权限。 - **文件是否已打开或被其他进程占用**:避免在多个会话中同时写入同一个文件。 - **文件大小限制**:检查文件系统是否已满或达到文件大小限制。 - **日志文件命名是否唯一**:避免因重复使用相同文件名导致文件写入失败。 例如,以下 PL/SQL 脚本展示了如何安全地使用 `UTL_FILE` 包并捕获异常: ```sql DECLARE file_handle UTL_FILE.FILE_TYPE; BEGIN file_handle := UTL_FILE.FOPEN('LOG_DIR', 'test.log', 'w'); UTL_FILE.PUT_LINE(file_handle, 'This is a test log entry.'); UTL_FILE.FCLOSE(file_handle); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error occurred: ' || SQLERRM); IF UTL_FILE.IS_OPEN(file_handle) THEN UTL_FILE.FCLOSE(file_handle); END IF; RAISE; END; ``` 在执行 `sqlplus` 脚本时,建议将 PL/SQL 块封装在异常处理结构中,以确保错误能够被捕获并输出到控制台或日志文件中。若脚本中涉及文件操作,应确保 `UTL_FILE` 所依赖的目录对象配置正确,且路径可访问。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值