我们做程序开发的经常要调试查看打印信息,特别是android,最常用的就是用adb logcat命令,很多时候我们都是用数据线连接电脑,用终端或者Eclipse软件来查看,如果应用在测试时报错又一时找不到设备,就会错失捕抓到错误信息的机会了;可能这个错误是随机出现的,那就要费更多时间去测试才能重现刚才的错误了。
很明显,我们需要一款能在安卓设备上查看logcat信息的应用,很幸运地是,电子市场上alogcat 就是这样的应用,它能显示出错误或异常的蛛丝马迹;alogcat 就是在代码里执行adb logcat 命令(详细的logcat命令说明请参考 Android的logcat用法),然后把它显示出来。但alogcat并不适合每个人,比如:alogcat必须打开才能显示出来;没有自动判断安卓设备是否root,如果你的机器没有root的话,你会发现选择root运行选项的话,一点信息都没有打印出来,也没有提示出来等等。但alogcat还是有其优点的,所以我参考了alogcat应用,在网上找来一些代码,修改整合成自己的日志查看器,和大家一起分享学习,希望对大家有帮助:
PS:自从安卓系统4.2或4.2以上的版本,查看其它应用的logcat 是需要root权限才能查看得到的,所以如果你发现打印的信息和电脑上看到的信息不同的话,很可能就是你的安卓手机或开发板没有root。
判断安卓手机或平板是否root过代码:
- //判断有没有 root权限
- public boolean requestRoot() {
- Process process = null;
- try {
- // Preform su to get root privledges
- process = Runtime.getRuntime().exec("su");
- // confirm that we have root
- DataOutputStream outputStream = new DataOutputStream(process.getOutputStream());
- outputStream.writeBytes("echo hello\n");
- // Close the terminal
- outputStream.writeBytes("exit\n");
- outputStream.flush();
- process.waitFor();
- if (process.exitValue() != 0) {
- Toast.makeText(mContext, R.string.not_root, Toast.LENGTH_LONG).show();
- return false;
- } else {
- // success
- Toast.makeText(mContext, R.string.root_success, Toast.LENGTH_LONG).show();
- return true;
- }
- } catch (IOException e) {
- Log.w("root", "Cannot obtain root");
- Toast.makeText(mContext, R.string.not_root, Toast.LENGTH_LONG).show();
- return false;
- } catch (InterruptedException e) {
- Toast.makeText(mContext, R.string.not_root, Toast.LENGTH_LONG).show();
- return false;
- }
- }
复制代码
Runtime.getRuntime().exec("su"); 这个是获取root权限,如果能获取得到root权限,我们可以用这个方法执行adb shell下的命令,随意修改系统文件,有root权限的安卓和开发板,请慎用这个方法,小心变砖!:lol
在代码中执行adb logcat 命令的核心代码:
- public void start() {
- // Log.d("alogcat", "starting ...");
- stop(); // stop EX
- mRunning = true;
- // command:执行线程 initialDelay:初始化延时 period:前一次执行结束到下一次执行开始的间隔时间(间隔执行延迟时间) unit:计时单位
- EX = Executors.newScheduledThreadPool(1);
- EX.scheduleAtFixedRate(catRunner, CAT_DELAY, CAT_DELAY,TimeUnit.SECONDS);
- try {
- Message m = Message.obtain(mHandler, LogActivity.CLEAR_WHAT);
- mHandler.sendMessage(m);
- List<String> progs = new ArrayList<String>();
- // logcat的命令参数
- if (TLogcatApplication.getRoot()) {
- Log.v("zxxroot", ">>>>>>>>root");
- progs.add("su");
- progs.add("-c");
- }
- progs.add("logcat");
- progs.add("-v");
- progs.add(mFormat.getValue());
- if (mBuffer != Buffer.MAIN) {
- progs.add("-b");
- progs.add(mBuffer.getValue());
- }
- progs.add("-s");
- progs.add("*:" + mLevel);
- logcatProc = Runtime.getRuntime().exec(progs.toArray(new String[progs.size()]));
- mReader = new BufferedReader(new InputStreamReader(logcatProc.getInputStream()), 1024);
- String line;
- // 不停在这里执行 会读出空的line 但也不为全空,还会有前面的标签zxxr tag 主要还是控制mRunning
- while (mRunning && ((line = mReader.readLine()) != null)) {
- if (!mRunning) {
- break;
- }
- if (line.length() == 0) {
- continue;
- }
- if (mIsFilterPattern) {
- if (mFilterPattern != null&& !mFilterPattern.matcher(line).find()) {
- continue;
- }
- } else {
- if (mFilter != null&& !line.toLowerCase().contains(mFilter.toLowerCase())) {
- continue;
- }
- }
- // 思路就是不停读出每一行数据,符合条件的就加入一个mLogCache,每隔一秒如果mLogCache有内容,就打印出来
- synchronized (mLogCache) {
- mLogCache.add(line);
- }
- }
- } catch (IOException e) {
- Log.e("alogcat", "error reading log", e);
- return;
- } finally {
- if (logcatProc != null) {
- logcatProc.destroy();
- logcatProc = null;
- }
- if (mReader != null) {
- try {
- mReader.close();
- mReader = null;
- } catch (IOException e) {
- Log.e("alogcat", "error closing stream", e);
- }
- }
- }
- }
复制代码
注意:这里要单独开一个线程来执行adb logcat命令,不然读到的数据和系统反馈的数据不同步;
EX会周期地读取mLogCache里面的内容,并通过handler发送消息更新listView;显示出来一行一行的日志其实就是一个listView。
后台日志记录用到前台服务的方法:
- try {
- mStartForeground = getClass().getMethod("startForeground", int.class, Notification.class);
- mStopForeground = getClass().getMethod("stopForeground", boolean.class);
复制代码
我们听歌的时候经常可以见到,音乐应用关闭之后,在通知栏出现可以控制音乐停播放的消息。在后台日志记录中我也用到类似这种方法,获得这个方法要用反射,反射不理解的请参考这个贴:java代码映射
在安卓手机或平板上测试的效果图如附件:
listView是每一行是由textView组成的,textView根据adb logcat的不同级别显示不同颜色。后台日志保存记录可以通过点击通知栏停止,即使应用关闭,后台日志保存还是在运行的。