如何实时展示日志(类似于LogCat)?

经理:Tank,我需要抓取应用的日志
我:你直接用AS的Logcat看不行吗?
经理:我是想在APP中直接查看日志,就像Logcat那样
我:明白了,就是做一个Logcat的功能呗
经理:是的

Okay,需求明朗了~搞一个APP来实时打印日志
首先,我们要知道如何获取日志呢?
if(你了解adb shell){
你会知道logcat这条命令;
}else{
我告诉你,我们可以通过这条命令打印日志;
}

我们先通过cmd执行下logcat看下效果:
在这里插入图片描述
从上面的效果图来看的话,我们是可以通过该指令实现想要的功能的,但是需要考虑几个问题:
1,频繁的读写,会不会导致ANR?
2,如此多的数据,如何展示?String会不会越界
针对第一个问题,我们可以创建一个子线程来进行日志的实时监听,然后通过Handler通知主线程进行日志的展示,为了方便大家熟悉Handler的原理,特附上链接

第二个问题,如果用一个String来保存所有的日志,百分百是会出现越界问题的。那么怎么解决?我选择用ScrollView中放一个竖直方向的LinearLayout,然后动态的添加TextView,每一行用一个String,这样总不会越界了吧哈哈。

问题解决之后,说干就干!
Step1:
界面布局,我们简单的创建一个ScrollView,内嵌一个LinearLayout,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/ll_content"
        android:orientation="vertical"/>


</ScrollView>

Step2:
开启子线程,监听Logcat

private void initLogger() {
        myThread = new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    Runtime runtime = Runtime.getRuntime();
                    proc = runtime.exec("su");
                    os = new DataOutputStream(proc.getOutputStream());
                    BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                    os.writeBytes("logcat -G 16m\n");
                    os.writeBytes("logcat\n");
                    os.flush();
                    String line;
                    currentTime = DateTimeUtil.getCurrentTimeMdHms(1000);
                    while ((line = in.readLine()) != null) {
                        if(needShow(line,currentTime)){
                            if(uiHandler!=null){
                                Message msg = new Message();
                                msg.obj = line;
                                uiHandler.sendMessage(msg);
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.i("wp error", e.toString());
                }
            }
        };
        myThread.start();
    }

需要注意几个问题
1,这里要申请ROOT权限,因为在非ROOT手机中,代码执行logcat只会打印应用自身的日志
2,logcat -G是修改日志缓存大小,安卓默认的是很小的,很容易异常结束监听
3,刚执行logcat的时候,会有大量的数据同时打印,即使用Handler机制还是会出现ANR,因此需要做一下时间的过滤(needShow方法)
Step3:
在Handler中动态添加TextView

private Handler uiHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            String content = (String)msg.obj;
            if(!TextUtils.isEmpty(content) && llContent!=null){
                TextView tv = new TextView(MainActivity.this);
                llContent.addView(tv,0);
            }
        }
    };

好了,至此我们便实现了一个简单的Logcat类似功能!

猜你喜欢

转载自blog.csdn.net/RobinTan24/article/details/108645335