一般在application中会做一些三方SDK等的初始化工作,收集这些初始化方法所消耗的精确时间,才能给我们提供优化的方向。
手动打点
手动打点,方法开始的地方埋点计时,方法结束的地方埋点,计算二者差值,可在适当时机上传到服务器进行数据分析。
一、普通方法:
先写一个工具类LanchTimer
private static long startT;
/**
* 起始时间
*/
public static void startTime(){
startT = System.currentTimeMillis();
}
/**
* 计算耗时
*/
public static void endTime(){
long costT = System.currentTimeMillis()-startT;
Log.e("LanchTimer cost",costT+"");
}
然后在application中使用,如在oncreate需要有两个初始化方法
@Override
public void onCreate() {
super.onCreate();
new GetDeviceIdTask(this);
new InitFrescoTask();
}
调用LanchTimer的计时方法,如下:
@Override
public void onCreate() {
super.onCreate();
LanchTimer.startTime();
new GetDeviceIdTask(this);
LanchTimer.endTime();
LanchTimer.startTime();
new InitFrescoTask();
LanchTimer.endTime();
}
这种方式很简单,基本人人都能想到,但是有很大的缺点:
1、如果oncreate中有很多初始化的方法,每个方法都这样写代码太冗余。
2、埋点代码跟业务代码耦合性太强。
二、AOP实现无侵入打点
1、AOP是什么
AOP:AOP为Aspect Oriented Programming的缩写,是面向切面编程。AOP是OOP的延续,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。具体aop的介绍可以参考:细说Spring——AOP详解(AOP概览)
2、引入AspectJ实现AOP
加入依赖
implementation 'org.aspectj:aspectjrt:1.8.+'
加上plugin
apply plugin: 'android-aspectjx'
在Android根目录的build.gradle 引入
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
具体实现代码
package com.example.pursue.performance.lanchPerformance;
import android.util.Log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/**
* AOp计算时间
*/
@Aspect
public class LanchTimerAop {
@Around("call(* com.example.pursue.androidperformance.PerformanceApplication.**(..))")
public void getTime(ProceedingJoinPoint joinPoint) {
Signature signature = joinPoint.getSignature();
String name = signature.toShortString();
long time = System.currentTimeMillis();
try {
joinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
Log.e(name + " getTime cost ",(System.currentTimeMillis() - time)+"");
}
}