I am trying to log the method execution time of every JAVA method in my app.
I tried many aspectj plugin such as uPhyca, aspectx but all fails due to Java 8 compatibility or gradle plugin compatibility or mostly because I am using data binding in my App. (I can't remove data binding because it is used wildly in the app). The I found Hugo. This is a plugin which can be used to log any method time in the app with @Debuggable
annotation. This project under the hood also used aspectj
I did not expected it to work with current gradle
but it works and even I can write my own Aspect classes which can be used to intercept methods. I wrote a class which can log method time here it is
@Aspect
public class LoggingAspect {
private static volatile boolean enabled = true;
private static DisposableObserver<List<LogData>> subscription;
private static final String TAG = LoggingAspect.class.getName();
final static ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(2);
@Pointcut("execution(* example.aspect.dunmmy(..))")
public void onClickEntryPoint() {
}
@Before("onClickEntryPoint()")
public void onClickBefore(JoinPoint joinPoint) {
Log.d(TAG, "Before Advice ==> Clicked on : " + joinPoint.getSignature().getName());
}
@Around("execution(* example.application..*(..))")
public Object onClickAround(ProceedingJoinPoint joinPoint) throws Throwable {
if (joinPoint != null && joinPoint.getTarget() != null) {
long startNanos = System.nanoTime();
Object result = joinPoint.proceed();
long stopNanos = System.nanoTime();
long lengthMillis = TimeUnit.NANOSECONDS.toMillis(stopNanos - startNanos);
if (lengthMillis <= 10) {
return result;
}
bufferResult(joinPoint, lengthMillis);
return result;
}
return joinPoint.proceed();
}
@After("onClickEntryPoint()")
public void onClickAfter(JoinPoint joinPoint) {
Log.d(TAG, "After Advice ==> Clicked on : " + joinPoint.getSignature().getName());
}
@AfterReturning(pointcut = "onClickEntryPoint()")
public void onClickAfterReturning() {
Log.d(TAG, "AfterReturning Advice ==>");
}
private static void bufferResult(ProceedingJoinPoint joinPoint, long lengthMillis) {
subscription = Observable.fromCallable(() -> {
LogData data = new LogData();
data.setClassName(joinPoint.getTarget().getClass().getSimpleName());
data.setMethodName(joinPoint.getSignature().getName());
data.setTimeTaken(lengthMillis);
return data;
}).buffer(2, TimeUnit.SECONDS)
.observeOn(Schedulers.from(threadPoolExecutor))
.observeOn(Schedulers.from(threadPoolExecutor))
.subscribeWith(new DisposableObserver<List<LogData>>() {
@Override
public void onNext(List<LogData> logData) {
for (LogData logDatum : logData) {
Log.e("time taken: ", logDatum.getClassName() + "=>" +
logDatum.getMethodName() + " " + "=> " + logDatum
.getTimeTaken() + "ms");
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}
It works fine and Log every method which is under example.application
but the problem arises that app got so slow that it takes 20-50 seconds to load an Activity or Fragment.
How can I tune the performance of the app. I don't know which part of the code is taking too long to run.