解决Android启动过程中Log丢失问题的方案

在Android开发中,遇到需要Debug启动过程中的问题时,往往会因为在启动过程中log丢失而异常麻烦,为此我们用了下面这个简单的方案。

假设你的应用或者framework的某些服务需要在开机时越快启动越好,那么在启动过程中某些log会丢失,但是程序的逻辑不会丢失,为此我们可以把需要分析的关键部位的log缓存在内存中,等到问题出现后系统稳定后再通过某些方式把缓存的log信息读出来,因为log是存在内存中的,所以不会有任何的丢失。

为了做到程序的灵活性,我们使用了检测文件是否存在来打开和关闭缓存功能,这样我们可以缓存功能的代码嵌入到程序本身,平时它都不会运行,只有当需要的时候,在特定的目录下建立一个文件后,它才会运行。同时为了不改变应用程序本身的代码就能读取缓存的信息,我们使用接收广播的形式来打印,下面是程序的源码,欢迎提供你的宝贵意见和建议:



package ;


import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.util.Log;


public class LogAssist {
    private static final String TAG = "LogAssist";


    //control command
    private static final String ACTION_PRINT = "action.logassist.print";
    private static final String ACTION_CONTROL_PAUSE = "action.logassist.control.pause";
    private static final String ACTION_CONTROL_RESUME = "action.logassist.control.resume";
    private static final String ACTION_CONTROL_CLEAR = "action.logassist.control.clear";


    //delay time to print the buffered log (ms)
    private static final String ACTION_EXTRA_DELAY2PRINT = "delay";
    //msg to print the log
    private static final int MSG_PRINT = 2008;
    //switch the log assist on or off by adding/removing this file
    private static final String SWITCHER_FILE = "/data/data/com./logassist_enabled";
    //maxium buffer used to cache the log
    private static final int MAX_BUFFER_SIZE = 10241000;
    //buffer size to clear when it is full
    private static final int BUFFER_SIZE_TO_CLEAR = 512;
    //start line of the log
    private static final String STR_LOG_START_LINE = "----------------LogAssist Print------------\n";
    static StringBuffer mLogBuffer;
    static SimpleDateFormat mDateFormat;
    static boolean mStarted = false;
    static int mPid;
    static Handler mPrintHandler = null;


    public static void init(Context context) {
        if (!needStart()) {
            Log.d(TAG, "LogAssist is not enabled.");
            return;
        }
        mLogBuffer = new StringBuffer(STR_LOG_START_LINE);
        mDateFormat = new SimpleDateFormat("dd-M-yyyy hh:mm:ss.SSS");
        mStarted = true;
        mPid = Process.myPid();
        registerControlReceiver(context);
        Log.d(TAG, "LogAssist is enabled.");
    }


    static class PrintHandlerCallBack implements Handler.Callback {
        
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_PRINT:
                print();
                break;
            }
            return false;
        }
    }
    private static void registerControlReceiver(Context context) {
        BroadcastReceiver controlReceiver = new BroadcastReceiver() {


            public void onReceive(Context context, Intent intent) {
                Log.d(TAG, "received intent :"+intent.getAction());
                if (intent == null) {
                    return;
                }
                String action = intent.getAction();
                if (ACTION_PRINT.equals(action)) {
                    int delay = intent.getIntExtra(ACTION_EXTRA_DELAY2PRINT, 0);
                    Log.d(TAG, " intent :delay="+delay);
                    if (delay <=0) {
                        print();
                    } else {
                        if (mPrintHandler == null) {
                            mPrintHandler = new Handler(new PrintHandlerCallBack());
                        }
                        mPrintHandler.sendEmptyMessageDelayed(MSG_PRINT, delay);
                    }
                } else if (ACTION_CONTROL_PAUSE.equals(action)) {
                    mStarted = false;
                }else if (ACTION_CONTROL_RESUME.equals(action)) {
                    mStarted = true;
                }else if (ACTION_CONTROL_CLEAR.equals(action)) {
                    mLogBuffer = new StringBuffer(STR_LOG_START_LINE);
                }
            }
        };
        IntentFilter ctrlIntentFilter = new IntentFilter();
        ctrlIntentFilter.addAction(ACTION_PRINT);
        ctrlIntentFilter.addAction(ACTION_CONTROL_PAUSE);
        ctrlIntentFilter.addAction(ACTION_CONTROL_RESUME);
        ctrlIntentFilter.addAction(ACTION_CONTROL_CLEAR);


        context.registerReceiver(controlReceiver, ctrlIntentFilter);
    }


    //check the switch file to see we need run log assist
    private static boolean needStart() {
        File switcher = new File(SWITCHER_FILE);
        return switcher.exists();
    }


    public static void log(String info) {
        if (!mStarted) {
            return;
        }
        if (mLogBuffer.length() >= MAX_BUFFER_SIZE) {
            //if buffer is full, remove first part defined by BUFFER_SIZE_TO_CLEAR
            if (mLogBuffer.length() > BUFFER_SIZE_TO_CLEAR) {
                //if the cached size is bigger than size to be cleared
                mLogBuffer.delete(0, BUFFER_SIZE_TO_CLEAR);
            } else {
                //if the cached size is not bigger than size to be cleared, reset the buffer
                mLogBuffer = new StringBuffer(STR_LOG_START_LINE);
            }
        }
        String date = mDateFormat.format(new Date());
        int tid = Process.myTid();


        mLogBuffer.append(date + "  " + mPid + "  " + tid + "    " + info + "\n");
    }


    private static void print() {
        if (mLogBuffer != null) {
            Log.i(TAG, mLogBuffer.toString());
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值