首先在Application onCreate 中初始化

// Builder. Not necessary while some plugins can be configured separately.
Matrix.Builder builder = new Matrix.Builder(this);
// Reporter. Matrix will callback this listener when found issue then emitting it.
builder.pluginListener(new TestPluginListener(this));
// Configure trace canary.
TracePlugin tracePlugin = configureTracePlugin(dynamicConfig);
builder.plugin(tracePlugin);
// Configure resource canary.
ResourcePlugin resourcePlugin = configureResourcePlugin(dynamicConfig);
builder.plugin(resourcePlugin);
// Configure io canary.
IOCanaryPlugin ioCanaryPlugin = configureIOCanaryPlugin(dynamicConfig);
builder.plugin(ioCanaryPlugin);
// Configure SQLite lint plugin.
SQLiteLintPlugin sqLiteLintPlugin = configureSQLiteLintPlugin();
builder.plugin(sqLiteLintPlugin);
// Configure battery canary.
BatteryMonitorPlugin batteryMonitorPlugin = configureBatteryCanary();
builder.plugin(batteryMonitorPlugin);
Matrix.init(builder.build());

初始化配置就生成了两样东西,一个是pluginListener 首要用于插件各个生命周期的监听回调,便利后续调查插件的状况

public class DefaultPluginListener implements PluginListener {
    private static final String TAG = "Matrix.DefaultPluginListener";
    private final Context context;
    public DefaultPluginListener(Context context) {
        this.context = context;
    }
    @Override
    public void onInit(Plugin plugin) {
        MatrixLog.i(TAG, "%s plugin is inited", plugin.getTag());
    }
    @Override
    public void onStart(Plugin plugin) {
        MatrixLog.i(TAG, "%s plugin is started", plugin.getTag());
    }
    @Override
    public void onStop(Plugin plugin) {
        MatrixLog.i(TAG, "%s plugin is stopped", plugin.getTag());
    }
    @Override
    public void onDestroy(Plugin plugin) {
        MatrixLog.i(TAG, "%s plugin is destroyed", plugin.getTag());
    }
    @Override
    public void onReportIssue(Issue issue) {
        MatrixLog.i(TAG, "report issue content: %s", issue == null ? "" : issue);
    }
}

然后生成不同监控功用的插件Plugin

最终经过传入初始化,真实的构建其实从builder,build开端,这是一种制作者形式

Matrix.init(builder.build());
private static volatile Matrix sInstance;
private final HashSet<Plugin> plugins;//插件调集
private final Application     application;
private final PluginListener  pluginListener; 
private Matrix(Application app, PluginListener listener, HashSet<Plugin> plugins) {
    this.application = app;
    this.pluginListener = listener;
    this.plugins = plugins;
    for (Plugin plugin : plugins) {
        plugin.init(application, pluginListener);
        pluginListener.onInit(plugin);
    }
}
public static void setLogIml(MatrixLog.MatrixLogImp imp) {
    MatrixLog.setMatrixLogImp(imp);
}
public static boolean isInstalled() {
    return sInstance != null;
}
public static Matrix init(Matrix matrix) {
    if (matrix == null) {
        throw new RuntimeException("Matrix init, Matrix should not be null.");
    }
    synchronized (Matrix.class) {
        if (sInstance == null) {
            sInstance = matrix;
        } else {
            MatrixLog.e(TAG, "Matrix instance is already set. this invoking will be ignored");
        }
    }
    return sInstance;
}
public static class Builder {
    private final Application application;
    private PluginListener pluginListener;
    private HashSet<Plugin> plugins = new HashSet<>();
    public Builder(Application app) {
        if (app == null) {
            throw new RuntimeException("matrix init, application is null");
        }
        this.application = app;
    }
    public Builder plugin(Plugin plugin) {
        String tag = plugin.getTag();
        for (Plugin exist : plugins) {
            if (tag.equals(exist.getTag())) {
                throw new RuntimeException(String.format("plugin with tag %s is already exist", tag));
            }
        }
        plugins.add(plugin);
        return this;
    }
    public Builder pluginListener(PluginListener pluginListener) {
        this.pluginListener = pluginListener;
        return this;
    }
    public Matrix build() {
        if (pluginListener == null) {
            pluginListener = new DefaultPluginListener(application);
        }
        return new Matrix(application, pluginListener, plugins);
    }
}

Matrix里持有一个插件的调集plugins,运用的是hashSet来保证不呈现重复,还有一个plugin状况的监听pluginListener。

Matrix采用了单例形式,volatile sInstance保证线程可见行,初始化的时分采用了两层查看在结构函数里给变量赋值并遍历plugins调集,并逐个调用插件的初始化办法plugin.init()和插件生命周期回调

for (Plugin plugin : plugins) {
    plugin.init(application, pluginListener);
    pluginListener.onInit(plugin);
}

那插件plugin是什么呢?咱们又是如何知道插件生命周期回调呢?下面是plugin的抽象类代码:

public abstract class Plugin implements IPlugin, IssuePublisher.OnIssueDetectListener, IAppForeground {
    private static final String TAG = "Matrix.Plugin";
    public static final int PLUGIN_CREATE = 0x00;
    public static final int PLUGIN_INITED = 0x01;
    public static final int PLUGIN_STARTED = 0x02;
    public static final int PLUGIN_STOPPED = 0x04;
    public static final int PLUGIN_DESTROYED = 0x08;
    private PluginListener pluginListener;
    private Application application;
    private boolean isSupported = true;
    private int status = PLUGIN_CREATE;
    @Override
    public void init(Application app, PluginListener listener) {
        if (application != null || pluginListener != null) {
            throw new RuntimeException("plugin duplicate init, application or plugin listener is not null");
        }
        status = PLUGIN_INITED;
        this.application = app;
        this.pluginListener = listener;
        AppActiveMatrixDelegate.INSTANCE.addListener(this);
    }
    @Override
    public void onDetectIssue(Issue issue) {
        if (issue.getTag() == null) {
            // set default tag
            issue.setTag(getTag());
        }
        issue.setPlugin(this);
        JSONObject content = issue.getContent();
        // add tag and type for default
        try {
            if (issue.getTag() != null) {
                content.put(Issue.ISSUE_REPORT_TAG, issue.getTag());
            }
            if (issue.getType() != 0) {
                content.put(Issue.ISSUE_REPORT_TYPE, issue.getType());
            }
            content.put(Issue.ISSUE_REPORT_PROCESS, MatrixUtil.getProcessName(application));
            content.put(Issue.ISSUE_REPORT_TIME, System.currentTimeMillis());
        } catch (JSONException e) {
            MatrixLog.e(TAG, "json error", e);
        }
        //MatrixLog.e(TAG, "detect issue:%s", issue);
        pluginListener.onReportIssue(issue);
    }
    @Override
    public Application getApplication() {
        return application;
    }
    @Override
    public void start() {
        if (isPluginDestroyed()) {
            throw new RuntimeException("plugin start, but plugin has been already destroyed");
        }
        if (isPluginStarted()) {
            throw new RuntimeException("plugin start, but plugin has been already started");
        }
        status = PLUGIN_STARTED;
        if (pluginListener == null) {
            throw new RuntimeException("plugin start, plugin listener is null");
        }
        pluginListener.onStart(this);
    }
    @Override
    public void stop() {
        if (isPluginDestroyed()) {
            throw new RuntimeException("plugin stop, but plugin has been already destroyed");
        }
        if (!isPluginStarted()) {
            throw new RuntimeException("plugin stop, but plugin is never started");
        }
        status = PLUGIN_STOPPED;
        if (pluginListener == null) {
            throw new RuntimeException("plugin stop, plugin listener is null");
        }
        pluginListener.onStop(this);
    }
    @Override
    public void destroy() {
        // stop first
        if (isPluginStarted()) {
            stop();
        }
        if (isPluginDestroyed()) {
            throw new RuntimeException("plugin destroy, but plugin has been already destroyed");
        }
        status = PLUGIN_DESTROYED;
        if (pluginListener == null) {
            throw new RuntimeException("plugin destroy, plugin listener is null");
        }
        pluginListener.onDestroy(this);
    }

plugin它是个抽象类,承继了IPlugin和 IssuePublisher.OnIssueDetectListener,IPlugin包含了五种插件的状况分别是CREATEINITEDSTARTEDSTOPPEDDESTROYED,当plugin状况发生变化时将回调交给pluginListener来处理。OnIssueDetectListener接口是IssuePublisher类里的内部接口,IssuePublisher具体作了两件事,记载问题和露出问题,其露出问题的办法便是空完成然后露出接口,交给完成OnIssueDetectListener接口的具体类来处理,Plugin承继了这个OnIssueDetectListener接口,但它也没自身处理,也是相同交留pluginListener来处理。

public interface IPlugin {
    Application getApplication();
    void init(Application application, PluginListener pluginListener);
    void start();
    void stop();
    void destroy();
    String getTag();
    void onForeground(boolean isForeground);
}

通关抽取插件公共的接口来束缚插件的写法,这样就完成不了不同功用插件的高度接耦,咱们只需要根据状况注册相应插件即可

在结构函数中还初始化了AppActiveMatrixDelegate

private Matrix(Application app, PluginListener listener, HashSet<Plugin> plugins) {
    this.application = app;
    this.pluginListener = listener;
    this.plugins = plugins;
    AppActiveMatrixDelegate.INSTANCE.init(application);
    for (Plugin plugin : plugins) {
        plugin.init(application, pluginListener);
        pluginListener.onInit(plugin);
    }
}

下面来看看AppActiveMatrixDelegate做了什么

public enum AppActiveMatrixDelegate {
    INSTANCE;
    private static final String TAG = "Matrix.AppActiveDelegate";
    private final Set<IAppForeground> listeners = new HashSet();
    private boolean isAppForeground = false;
    private String visibleScene = "default";
    private Controller controller = new Controller();
    private boolean isInit = false;
    private String currentFragmentName;
    private Handler handler;
    public void init(Application application) {
        if (isInit) {
            MatrixLog.e(TAG, "has inited!");
            return;
        }
        this.isInit = true;
        if (null != MatrixHandlerThread.getDefaultHandlerThread()) {
            this.handler = new Handler(MatrixHandlerThread.getDefaultHandlerThread().getLooper());
        }
        application.registerComponentCallbacks(controller);
        application.registerActivityLifecycleCallbacks(controller);
    }

枚举类,惊不惊喜,这也是Java单例形式形式的一种,线程安全而且性能高效 初始化生成了自己的 HandlerThread便于后期做一些线程操作,后序章节细说。 之后注册了相关的生命周期监听和体系内存状况监听,进入controller看看

private final class Controller implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {
    @Override
    public void onActivityStarted(Activity activity) {
        updateScene(activity);
        onDispatchForeground(getVisibleScene());
    }
    @Override
    public void onActivityStopped(Activity activity) {
        if (getTopActivityName() == null) {
            onDispatchBackground(getVisibleScene());
        }
    }
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    }
    @Override
    public void onActivityDestroyed(Activity activity) {
    }
    @Override
    public void onActivityResumed(Activity activity) {
    }
    @Override
    public void onActivityPaused(Activity activity) {
    }
    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    }
    @Override
    public void onLowMemory() {
    }
    @Override
    public void onTrimMemory(int level) {
        MatrixLog.i(TAG, "[onTrimMemory] level:%s", level);
        if (level == TRIM_MEMORY_UI_HIDDEN && isAppForeground) { // fallback
            onDispatchBackground(visibleScene);
        }
    }
}

OnTrimMemory Android 4.0 之后供给的一个API,首要作用是提示开发者在体系内存不足的时分,经过处理部分资源来释放内存,从而防止被 Android 体系杀死。

ActivityLifecycleCallbacks 能够监听整个App activity栈的进出状况,通关生命周期的判别能够知道App是否在前后台,当前页面的Activity信息,这是开发基础sdk的必备常识

咱们看下APP进入前后台的具体操作

private void onDispatchForeground(String visibleScene) {
    if (isAppForeground || !isInit) {
        return;
    }
    MatrixLog.i(TAG, "onForeground... visibleScene[%s]", visibleScene);
    handler.post(new Runnable() {
        @Override
        public void run() {
            isAppForeground = true;
            synchronized (listeners) {
                for (IAppForeground listener : listeners) {
                    listener.onForeground(true);
                }
            }
        }
    });
}
private void onDispatchBackground(String visibleScene) {
    if (!isAppForeground || !isInit) {
        return;
    }
    MatrixLog.i(TAG, "onBackground... visibleScene[%s]", visibleScene);
    handler.post(new Runnable() {
        @Override
        public void run() {
            isAppForeground = false;
            synchronized (listeners) {
                for (IAppForeground listener : listeners) {
                    listener.onForeground(false);
                }
            }
        }
    });
}

所以该类便是一个前后台监听类而已,由于前后台生命周期的感知对于性能监控组件非常重要。需要注意的是咱们用的是自己的Handler,一 由于循环和处理或许存在耗时,在子线程中进行,二 是一致一个hander能够保证履行的时序性,这个特点在埋点,性能监控上非常重要。

该类的监听在Plugin抽象类已经经过下面办法进行了注册

public void addListener(IAppForeground listener) {
    synchronized (listeners) {
        listeners.add(listener);
    }
}

最终看下类结构图

腾讯性能监控框架Matrix源码分析(二)初始化和架构设计

插件注册的流程图

腾讯性能监控框架Matrix源码分析(二)初始化和架构设计

总结

简单做个回忆,经过进口初始化层层剥离,咱们知道了整个Matrix的框架结构规划,以及类的结构规划这样有利于咱们从全体到部分的学习。咱们也知道了相关规划形式的运用,单例,制作者,调查者。以及如何经过抽取接口束缚插件,一致注册到hashset来完成解耦,还有生命周期前后台的监控技巧,handler线程的运用办法。接下来我会去重视每一个插件的功用,接口界说的办法,一个个去翻源码,看下到底是怎么样的完成,才能做到监控。期待我的扮演,谢谢点个赞,你们是我最大的动力。