Step 1. Add the JitPack repository to your build file
Add it in your root build.gradle at the end of repositories:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Add it in your build.sbt at the end of resolvers:
resolvers += "jitpack" at "https://jitpack.io"
Add it in your project.clj at the end of repositories:
:repositories [["jitpack" "https://jitpack.io"]]
Step 2. Add the dependency
dependencies {
implementation 'com.github.vincentbrison:GradleAspectJ-Android:2.2.2'
}
<dependency>
<groupId>com.github.vincentbrison</groupId>
<artifactId>GradleAspectJ-Android</artifactId>
<version>2.2.2</version>
</dependency>
libraryDependencies += "com.github.vincentbrison" % "GradleAspectJ-Android" % "2.2.2"
:dependencies [[com.github.vincentbrison/GradleAspectJ-Android "2.2.2"]]
A Gradle plugin which enables AspectJ for Android builds.
Supports writing code with AspectJ-lang in .aj
files and in java-annotation style.
Full support of Android product flavors and build types.
Support Kotlin, Groovy, Scala and any other languages that compiles into java bytecode.
Actual version: com.archinamon:android-gradle-aspectj:2.2.2
.
Re-written with brand new <a href="http://tools.android.com/tech-docs/new-build-system/transform-api" target="_blank">Transform API</a>!
This plugin is completely friendly with <a href="https://bitbucket.org/hvisser/android-apt" target="_blank">APT</a> (Android Annotation Processing Tools) and <a href="https://github.com/evant/gradle-retrolambda/" target="_blank">Retrolambda</a> project (but Java 8 not supported in .aj files). <a href="https://github.com/excilys/androidannotations" target="_blank">AndroidAnnotations</a>, <a href="https://github.com/square/dagger" target="_blank">Dagger</a> are also supported and works fine.
This plugin has many ideas from the others similar projects, but no one of them grants full pack of features like this one. Nowdays it has been completely re-written using Transform API.
Augments Java, Kotlin, Groovy bytecode simultaneously!<br /> Works with background mechanics of jvm-based languages out-of-box!<br /> How to teach Android Studio to understand the AspectJ!
It is easy to isolate your code with aspect classes, that will be simply injected via cross-point functions, named advices
, into your core application. The main idea is — code less, do more!
AspectJ-Gradle plugin provides supply of all known JVM-based languages, such as Groovy, Kotlin, etc. That means you can easily write cool stuff which may be inject into any JVM language, not only Java itself! :)
To start from you may look at my <a href="https://github.com/Archinamon/AspectJExampleAndroid" target="_blank">example project</a>. And also you may find useful to look at <a href="https://eclipse.org/aspectj/doc/next/quick5.pdf" target="_blank">reference manual</a> of AspectJ language and simple <a href="https://eclipse.org/aspectj/sample-code.html" target="_blank">code snipets</a>. In case aspectj-native not supported by Android Studio, you may write a java-classes with aspectj annotations.
May not work with InstantRun due to a slicer bug. Please, <a href="http://stackoverflow.com/a/35169716/483603" target="_blank">switch off InstanceRun</a> if you have faced any problems (e.g. class file not found in DexPath in runtime).
Two simple rules you may consider when writing aspect classes.
src/$flavor/aspectj
source set! These aj-classes will be excluded from java compiler.These rules affects only in case you're writing in native aj-syntax. You may write aspects in java-annotation style and being free from these limitations.
First add a maven repo link into your repositories
block of module build file:
mavenCentral()
maven { url "https://jitpack.io" }
Don't forget to add mavenCentral()
due to some dependencies inside AspectJ-gradle module.
Add the plugin to your buildscript
's dependencies
section:
classpath 'com.github.Archinamon:GradleAspectJ-Android:2.2.2'
Apply the aspectj
plugin:
apply plugin: 'com.archinamon.aspectj'
Now you can write aspects using annotation style or native (even without IntelliJ IDEA Ultimate edition). Let's write simple Application advice:
import android.app.Application;
import android.app.NotificationManager;
import android.content.Context;
import android.support.v4.app.NotificationCompat;
aspect AppStartNotifier {
pointcut postInit(): within(Application) && execution(* Application.onCreate());
after() returning: postInit() {
Application app = (Application) thisJoinPoint.getTarget();
NotificationManager nmng = (NotificationManager) app.getSystemService(Context.NOTIFICATION_SERVICE);
nmng.notify(9999, new NotificationCompat.Builder(app)
.setTicker("Hello AspectJ")
.setContentTitle("Notification from aspectJ")
.setContentText("privileged aspect AppAdvice")
.setSmallIcon(R.drawable.ic_launcher)
.build());
}
}
aspectj {
ajc '1.8.9'
includeJar 'design', 'support-v4', 'dagger'
includeAspectsFromJar 'my-aj-logger-lib', 'any-other-libs-with-aspects'
ajcExtraArgs << '-referenceInfo' << '-warn:deprecation'
weaveInfo true
debugInfo false
addSerialVersionUID false
noInlineAround false
ignoreErrors false
breakOnError true
experimental false
logFileName 'ajc-details.log'
}
ajc
Allows to define the aspectj runtime jar version manually (1.8.9 current)
includeJar
Name filter to include any jar/aar which name or path satisfies the filter
includeAspectsFromJar
Name filter to include any jar/aar with compiled binary aspects you wanna affect your projectajcExtraArgs
Additional parameters for aspectj compiler
weaveInfo
Enables printing info messages from Aj compiler
debugInfo
Adds special debug info in aspect's bytecodeaddSerialVersionUID
Adds serialVersionUID field for Serializable-implemented aspect classesnoInlineAround
Strict ajc to inline around advice's body into the target methodsignoreErrors
Prevent compiler from aborting if errors occurrs during processing the sources
breakOnError
Allows to continue project building when ajc fails or throws any errors
experimental
Enables experimental ajc options: -XhasMember
and -Xjoinpoints:synchronization,arrayconstruction
. More details in <a href="https://github.com/Archinamon/GradleAspectJ-Android/issues/18" target="_blank">issue #18</a>
logFileName
Defines name for the log file where all Aj compiler info writes to
Just write a test and run them! If any errors occurrs please write an issue :)
Correct tuning will depends on your own usage of aspect classes. So if you declares inter-type injections you'll have to predict side-effects and define your annotations/interfaces which you inject into java classes/methods/etc. in proguard config.
Basic rules you'll need to declare for your project:
-adaptclassstrings
-keepattributes InnerClasses, EnclosingMethod, Signature, *Annotation*
-keepnames @org.aspectj.lang.annotation.Aspect class * {
ajc* <methods>;
}
If you will face problems with lambda factories, you may need to explicitely suppress them. That could happen not in aspect classes but in any arbitrary java-class if you're using Retrolambda. So concrete rule is:
-keep class *$Lambda* { <methods>; }
-keepclassmembernames public class * {
*** lambda*(...);
}
updated
2.2.0 artifacts;AspectJ-gradle
to android-gradle-aspectj
;weaveTests
;app/build/ajc_details.log
;src/main/aspectj/path.to.package.Aspect.aj
;All these limits are fighting on and I'll be glad to introduce new build as soon as I solve these problems.
Copyright 2015 Eduard "Archinamon" Matsukov.
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.