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中需要有权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.inaka.galgo">    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />    <application android:allowBackup="true" android:label="@string/app_name">        <service android:name=".GalgoService" />    </application></manifest>


改造了一下代码,

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<GalgoOptions> CREATOR = new Creator<GalgoOptions>()        {            @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<String> 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<String> 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

更多相关文章

  1. Android之PreferenceActivity(配置界面详解)
  2. setContentView( )方法
  3. NDK DEBUG方法
  4. Android(安卓)java.lang.StackOverflowError at android.view.Vi
  5. android Toast 重复显示问题
  6. android常用控件一二
  7. TSwitch 中文简繁显示支持(XE6 Android)
  8. Android(安卓)沉浸式状态栏 最通俗易懂的总结
  9. 关于ScrollView嵌套RecyclerView时RecyclerView不显示的问题

随机推荐

  1. ActionBar
  2. Android(安卓)activity属性设置大全
  3. Android开发EditText属性
  4. 【Android】Android(安卓)apk默认安装位
  5. android底层开发-android基础架构
  6. Android_传感器综述
  7. Android(安卓)SVG动画PathView源码解析与
  8. Android(安卓)Studio 导出 .aar包的操作
  9. ListView之setEmptyView的问题
  10. activity属性设置大全