25 January 2015

小米01月第四周工作记录


01.25 - 01.29

扒 MIUI 的相机摄像代码

总结 android log 技巧。用 Eclipse 的logcat工具可以显示某个 Tag 的log,或者某个 App 的各种等级的log。 但有时候会想 显示某个App的除了某几个 log 外的所有 log,比如最近的Camera项目,tag 为 “dalvikvm” 的log会不断输出,提示剩余的内存,这种 log 我们调试时暂时不想关心。

一段Shell脚本 显示某个 App 的所有log

#!/bin/bash  
packageName=$1  
pid=`adb shell ps | grep $packageName | awk '{print $2}'`  
adb logcat | grep --color=auto $pid  

上述这个脚本首先得到你的 App 的进程号,然后用 grep 显示。 之后再用 grep -v 可以指定不显示,如果这行包含某个字符串。

保存上述脚本为 myandroidlog.sh , 加入环境变量,这样我们可以用

myandroidlog com.xiaomi.shank | grep -v "^..dalvikvm\|^..Microlog" 显示 com.xiaomi.shank 除了 Tag 为 dalvikvmMicrolog 外的所有 log。 但是多管道会有一个问题,第二级管道中的流不到一定量不会及时输出到第三级管道中。这样会造成 log 不能及时显示。 之后查了 sed ,没折腾起来 ,后来自己写了个java程序结合正则表达式接受外部输入流处理。

//{java}
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;

    public class MyLogFilter {
        public static boolean isProcessId(String arg) {
        char c = arg.charAt(0);
        if (c >= '0' && c <= '9') {
        return true;
        }
        return false;
        }

        public static void main(String args[]) {
        // args = new String []{"16144","16824","heelo","16824"};
        int processIdCount = 0;
        int processTailCount = 0;
        List<String> selected = new ArrayList<String>();
        for (String arg : args) {
        if (isProcessId(arg)) {
        processIdCount++;
        selected.add(arg);
        } else {
        break;
        }
        }
        for (int i = args.length - 1; i >= 0; i--) {
        String arg = args[i];
        if (isProcessId(arg)) {
        processTailCount++;
        selected.remove(arg);
        } else {
        break;
        }
        }

        StringBuilder pidRegex = new StringBuilder("[\\s|\\S]*(");
        for (int i = 0; i < selected.size(); i++) {
        String pid = selected.get(i);
        if (i != 0)
        pidRegex.append("|");
        pidRegex.append(pid);
        }
        pidRegex.append(")").append("[\\s|\\S]*");
        StringBuilder sb = new StringBuilder("^..(");
        for (int i = processIdCount; i < args.length-processTailCount; i++) {
        if (i != processIdCount) {
        sb.append("|");
        }
        sb.append(args[i]);
        }
        sb.append(")").append("[\\s|\\S]*");
        String pattern = sb.toString();
        String pidPattern = pidRegex.toString();
        Scanner sc = new Scanner(System.in);
        System.out.println(pidPattern);
        System.out.println(pattern);

        while (sc.hasNextLine()) {
        String line = sc.nextLine();
        if (line.matches(pidPattern)) {
        if (line.matches(pattern)) {
        } else {
        if (line.startsWith("E")) {
        line = "*****" + line;
        }
        System.out.println(line);
        }
        }
        }
        }
    }

这样

cd ~/Desktop
adb logcat | java MyLogFilter $pid dalvikvm Microlog 18844 18824

就能达到 演示某个App所有的log,但是可以指定不显示的Tag。pid为该进程所有的pid,可能有多个(多进程app),最后面的数字是该app不显示的进程号。

handler.post(Runnable r) , r.run() 是运行在 main 线程里的。



blog comments powered by Disqus