Android开发中需要迅速定位问题,在Android 屏幕上打印LOG,是一个很好的通道

基本的思路:启动LogService读取指定log,使用WindowManager展示到屏幕上

直接上代码

public class LogService extends Service {

private ListView listview;
private LinkedList<LogLine> logList = new LinkedList<LogLine>();
private LogAdapter mAdapter;
private final int MAX_LINE = 500;
private SimpleDateFormat LOGCAT_TIME_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS");
private Thread readLog;
private boolean isAllowReadLog = false;

@Override
public IBinder onBind(Intent arg0) {
return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

//Utility.LOG_TAG 为自定义的logString,service会读取此log

readLog = new Thread(new LogReaderThread(Utility.LOG_TAG));
readLog.start();
createSystemWindow();
isAllowReadLog = true;
return START_STICKY;
}

@Override
public void onDestroy() {
removeSystemWindow();
isAllowReadLog = false;
super.onDestroy();
}

private void createSystemWindow() {
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 0, PixelFormat.TRANSLUCENT);
// lp.gravity=Gravity.LEFT|Gravity.TOP; //调整悬浮窗口至左上角
// 以屏幕左上角为原点,设置x、y初始化
// lp.x=0;
// lp.y=0;
final LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
listview = (ListView) inflator.inflate(R.layout.log_window, null);
logList = new LinkedList<LogLine>();
mAdapter = new LogAdapter(this, logList);
listview.setAdapter(mAdapter);
if (isAllowReadLog) {
wm.addView(listview, lp);
}

}

private void removeSystemWindow() {
if (listview != null && listview.getParent() != null) {
final WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.removeViewImmediate(listview);
}
}

class LogAdapter extends ArrayAdapter<LogLine> {

private LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

public LogAdapter(Context context, List<LogLine> objects) {
super(context, 0, objects);
}

public void add(LogLine line) {
logList.add(line);
notifyDataSetChanged();
}

@Override
public LogLine getItem(int position) {
return logList.get(position);
}

@Override
public int getCount() {
return logList.size();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
LogLine line = getItem(position);
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflator.inflate(R.layout.log_line, parent, false);
holder.time = (TextView) convertView.findViewById(R.id.log_time);
holder.content = (TextView) convertView.findViewById(R.id.log_content);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.time.setText(line.time);
holder.content.setText(line.content);
if (line.color != 0) {
holder.content.setTextColor(line.color);
} else {
holder.content.setTextColor(getResources().getColor(android.R.color.white));
}
return convertView;
}

}

class ViewHolder {
public TextView time;
public TextView content;
}

class LogReaderThread implements Runnable {

private String filter;

public LogReaderThread(String filter) {
this.filter = filter;
}

@Override
public void run() {
Process mLogcatProc = null;
BufferedReader reader = null;
try {
mLogcatProc = Runtime.getRuntime().exec(new String[] { "logcat", filter + " *:S" });
reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream()));
String line;

while (isAllowReadLog) {
if ((line = reader.readLine()) != null) {
Message msg = new Message();
msg.obj = line;
handler.sendMessage(msg);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

private void buildLogLine(String line) {
LogLine log = new LogLine();
log.time = LOGCAT_TIME_FORMAT.format(new Date()) + ": ";
if (line.startsWith("I")) {
log.color = Color.parseColor("#008f86");
} else if (line.startsWith("V")) {
log.color = Color.parseColor("#fd7c00");
} else if (line.startsWith("D")) {
log.color = Color.parseColor("#8f3aa3");
} else if (line.startsWith("E")) {
log.color = Color.parseColor("#fe2b00");
}
if (line.contains(")")) {
line = line.substring(line.indexOf(")") + 1, line.length());
}
log.content = line;

while (logList.size() > MAX_LINE) {
logList.remove();
}
mAdapter.add(log);
}

private Handler handler = new Handler() {
public void handleMessage(Message msg) {
buildLogLine(msg.obj.toString());
};
};

}

//实体类

public class LogLine {

public String time;
public String content;
public int color;

}

启动server,log将输出到屏幕上,Android共勉!

更多相关文章

  1. android appwidget service的初始化
  2. Android初始化语言 (init.*.rc、init.conf文件格式)
  3. android注解初始化view
  4. Android 应用初始化及窗体事件的分发
  5. [android]初始化代码仓库时出现“OSError: [Errno 2] No such fi
  6. [Android]自定义图片左上角斜着的View
  7. Android 初始化之Zygote
  8. Android init language (安卓初始化语言)

随机推荐

  1. webrtc 之android与PC互通
  2. Android的消息机制,用Android线程间通信的
  3. android基本架构
  4. Android自定义视图二:用Canvas和Paint绘制
  5. Android Studio打包apk,aar,jar包 总结
  6. android 发送语音功能和ios交互格式aac
  7. Android(安卓)Material Design 之 Bottom
  8. 巨好的入门写精通
  9. Android 月活跃人数超过10亿用户了,我却审
  10. Android菜鸟的成长笔记(15)—— Android中