java 日志显示控件_在屏幕上显示日志的Android类库

Galgo是Android日志类库,用于在屏幕上显示应用的日志信息。这对于测试人员和开发人员非常有用,可以根据屏幕上的日志文件了解应用出现BUG时发生的事情。

可以定义屏幕上显示日志的背景颜色、文本颜色、文本大小和日志显示的行数。

https://github.com/inaka/galgo

public class ExampleActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_example);

// add some customization to the log messages

GalgoOptions options = new GalgoOptions.Builder()

.numberOfLines(15)

.backgroundColor(Color.parseColor("#D9d6d6d6"))

.textColor(Color.BLACK)

.textSize(15)

.build();

Galgo.enable(this, options);

Galgo.log("I am a log message");

}

public void onDestroy() {

super.onDestroy();

// always call disable to avoid memory leaks

Galgo.disable(this);

}

}

其实就是一个Service上面显示了一个window Menifest中需要有权限

aa0949dbbbdd653fee949746b4f9ec70.png

改造了一下代码,

1.把Service做成一个全局的, 而不是bind到唯一的Activity , 这才是全局的Log

2.把GalgoOptions 放到了Galgo.java中

/*

* Copyright (C) 2014 Inaka.

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*

* @author Henrique Boregio (henrique@inakanetworks.com)

*/

package com.kookong.tv.debug;

import android.content.Context;

import android.content.Intent;

import android.content.pm.PackageManager;

import android.os.Handler;

import android.os.Looper;

import android.os.Message;

import android.os.Parcel;

import android.os.Parcelable;

import android.util.Log;

import com.hzy.tvmao.TmApp;

public class Galgo

{

private static final Handler UI_HANDLER = new Handler(Looper.getMainLooper())

{

@Override

public void handleMessage(Message msg) {

if (!isServiceRunning) {//service 停止了就不要往service发消息了

return;

}

String message = (String) msg.obj;

Intent intent = new Intent(TmApp.getContext(), GalgoService.class);

intent.putExtra(MESSAGE, message);

TmApp.getContext().startService(intent);

}

};

public static final String MESSAGE = "galgo.message";

public static final String ARG_OPTIONS = "galgo.options";

private static final String TAG = "Galgo";

private static GalgoOptions sOptions;

private static Context sContext;

private static boolean isServiceRunning;

/**

* * Starts a new Galgo with custom {@link com.inaka.galgo.GalgoOptions}

*

* @param context

* Context

* @param options

* Custom {@link com.inaka.galgo.GalgoOptions}

*/

public static void enable(GalgoOptions options) {

sOptions = options;

init();

}

/**

* Starts a new Galgo with default {@link com.inaka.galgo.GalgoOptions}

*

* @param context

* Context

*/

public static void enable() {

enable(new GalgoOptions.Builder().build());

}

private static void init() {

sContext = TmApp.getContext();

checkPermission(sContext);

// start a new service with our options

Intent intent = new Intent(sContext, GalgoService.class);

intent.putExtra(ARG_OPTIONS, sOptions);

TmApp.getContext().startService(intent);

isServiceRunning = true;

}

public static void disable() {

Intent intent = new Intent(sContext, GalgoService.class);

sContext.stopService(intent);

sContext = null;

isServiceRunning = false;

}

/**

* Logs a String message to the screen. This String will be overlayed on top

* of the UI elements currently displayed on screen. As a side effect, this

* message will also be logged to the standard output via

* {@link android.util.Log}.

*

* @param message

* String to be displayed

*/

public static void log(String message) {

Log.i(TAG, message);

Message msg = UI_HANDLER.obtainMessage(0, message);

msg.sendToTarget();

}

private static void checkPermission(Context context) {

String permission = "android.permission.SYSTEM_ALERT_WINDOW";

int status = context.checkCallingOrSelfPermission(permission);

if (status == PackageManager.PERMISSION_DENIED) {

throw new IllegalStateException("in order to use Galgo, " + "please add the permission " + permission + " to your AndroidManifest.xml");

}

}

public static final class GalgoOptions implements Parcelable

{

public final int numberOfLines;

public final int backgroundColor;

public final int textColor;

public final int textSize;

/**

* Contains options for Galgo. Defines

*

* @param builder

*/

private GalgoOptions(Builder builder) {

numberOfLines = builder.numberOfLines;

backgroundColor = builder.backgroundColor;

textColor = builder.textColor;

textSize = builder.textSize;

}

/**

* Builder for {@link com.inaka.galgo.GalgoOptions}

*/

public static class Builder

{

private int numberOfLines = 10;

private int backgroundColor = 0xD993d2b9;

private int textColor = 0xFFFFFFFF;

private int textSize = 10;

/**

*

* @param n

* number of lines

* @return

*/

public Builder numberOfLines(int n) {

ensurePositiveInt(n, "number of lines must be > 0");

numberOfLines = n;

return this;

}

/**

* Sets the background color of the log messages

*

* @param color

* @return

*/

public Builder backgroundColor(int color) {

backgroundColor = color;

return this;

}

/**

* Sets the text color of the log messages

*

* @param color

* @return

*/

public Builder textColor(int color) {

textColor = color;

return this;

}

/**

* Sets the text size of the messages

*

* @param size

* @return

*/

public Builder textSize(int size) {

ensurePositiveInt(size, "text size must be > 0");

textSize = size;

return this;

}

/**

* Creates a {@link com.inaka.galgo.GalgoOptions} with the

* customized parameters

*

* @return

*/

public GalgoOptions build() {

return new GalgoOptions(this);

}

}

private static void ensurePositiveInt(int value, String msg) {

if (value <= 0) {

throw new IllegalArgumentException(msg);

}

}

// Parcelable implementation

private GalgoOptions(Parcel source) {

numberOfLines = source.readInt();

backgroundColor = source.readInt();

textColor = source.readInt();

textSize = source.readInt();

}

public static final Creator CREATOR = new Creator()

{

@Override

public GalgoOptions createFromParcel(Parcel source) {

return new GalgoOptions(source);

}

@Override

public GalgoOptions[] newArray(int size) {

return new GalgoOptions[size];

}

};

@Override

public int describeContents() {

return 0; // No special content.

}

@Override

public void writeToParcel(Parcel dest, int flags) {

dest.writeInt(numberOfLines);

dest.writeInt(backgroundColor);

dest.writeInt(textColor);

dest.writeInt(textSize);

}

}

}

/*

* Copyright (C) 2014 Inaka.

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*

* @author Henrique Boregio (henrique@inakanetworks.com)

*/

package com.kookong.tv.debug;

import java.util.ArrayDeque;

import java.util.Collection;

import java.util.Queue;

import android.app.Service;

import android.content.Intent;

import android.graphics.PixelFormat;

import android.os.Binder;

import android.os.IBinder;

import android.text.Spannable;

import android.text.SpannableString;

import android.text.TextUtils;

import android.text.style.BackgroundColorSpan;

import android.view.Gravity;

import android.view.WindowManager;

import android.widget.TextView;

import com.hzy.tvmao.utils.LogUtil;

import com.hzy.tvmao.utils.SystemUtil;

import com.kookong.tv.debug.Galgo.GalgoOptions;

public class GalgoService extends Service

{

private TextView mTextView;

private GalgoOptions mOptions;

private final Queue mLines = new ArrayDeque<>();

@Override

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

LogUtil.d("onStartCommand");

//首次创建有options

GalgoOptions options = intent.getExtras().getParcelable(Galgo.ARG_OPTIONS);

if (options != null) {

mOptions = options;

}

//显示log的时候有Message

String message = intent.getExtras().getString(Galgo.MESSAGE);

if (!TextUtils.isEmpty(message)) {

displayText(message);

}

return super.onStartCommand(intent, flags, startId);

}

@Override

public void onCreate() {

super.onCreate();

mTextView = new TextView(this);

WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);

wm.addView(mTextView, params);

}

public void displayText(String text) {

mLines.add(text);

if (mLines.size() > mOptions.numberOfLines) {

mLines.poll();

}

redraw(mLines);

}

private void redraw(Collection texts) {

mTextView.setTextSize(mOptions.textSize);

mTextView.setTextColor(mOptions.textColor);

mTextView.setPadding(SystemUtil.getScreenWH()[0] / 4, 0, 0, 0);

Spannable spannable = new SpannableString(TextUtils.join("\n", texts));

spannable.setSpan(new BackgroundColorSpan(mOptions.backgroundColor), 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

mTextView.setText(spannable);

}

@Override

public void onDestroy() {

super.onDestroy();

if (mTextView != null) {

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);

wm.removeView(mTextView);

}

}

@Override

public IBinder onBind(Intent intent) {

return null;

}

}

另一个开源项目, 显示所有日志

https://github.com/jgilfelt/GhostLog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值