AspectJ: a facet oriented framework
1.1 download: http://www.eclipse.org/downloads/download.php?file=/tools/aspectj/aspectj-1.8.13.jar
1.2 direct installation
1.3 create a new application and add configuration in build.gradle: copy the complete code here
apply plugin: 'com.android.application'
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.aspectj:aspectjtools:1.8.13'
classpath 'org.aspectj:aspectjweaver:1.8.13'
}
}
repositories {
mavenCentral()
}
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
defaultConfig {
applicationId "com.example.a02_aop"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
final def log = project.logger
final def variants = project.android.applicationVariants
variants.all { variant ->
if (!variant.buildType.isDebuggable()) {
log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")
return;
}
JavaCompile javaCompile = variant.javaCompile
javaCompile.doLast {
String[] args = ["-showWeaveInfo",
"-1.8",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]
log.debug "ajc args: " + Arrays.toString(args)
MessageHandler handler = new MessageHandler(true);
new Main().run(args, handler);
for (IMessage message : handler.getMessages(null, true)) {
switch (message.getKind()) {
case IMessage.ABORT:
case IMessage.ERROR:
case IMessage.FAIL:
log.error message.message, message.thrown
break;
case IMessage.WARNING:
log.warn message.message, message.thrown
break;
case IMessage.INFO:
log.info message.message, message.thrown
break;
case IMessage.DEBUG:
log.debug message.message, message.thrown
break;
}
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:27.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
compile files('libs/aspectjrt.jar')
}
1.4 copy a development package under the installation directory: aspectjrt.jar
After the completion of the appeal configuration, start to write the code. First, analyze the main functions. If there is a net, click the button to jump. If there is no net, it will not jump
First add comments: checkNet
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckNet {
}
Then use AOP facet. First, find the Pointcut("execution (full path of annotation * (..))"), then find the facet @ Around("the method to find the pointcut above") public Object checkNet(ProceedingJoinPoint joinPoint) throws Throwable {}, complete code
@Aspect
public class SectionAspect {
/**
* Find the tangent point of processing
* * *(..) Can handle all methods
*/
@Pointcut("execution(@com.example.a02_aop.CheckNet * *(..))")
public void checkNetBehavior() {
}
/**
* Processing section
*/
@Around("checkNetBehavior()")
public Object checkNet(ProceedingJoinPoint joinPoint) throws Throwable {
Log.e("TAG", "checkNet");
//Get CheckNet comments
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
CheckNet checkNet = signature.getMethod().getAnnotation(CheckNet.class);
if (checkNet != null) {
Object object = joinPoint.getThis();
Context context = getContext(object);
if (context != null) {
//Judge whether there is network
if (!isNetworkAvailable(context)) {
//No net returns null
Toast.makeText(context, "Please check the Internet", Toast.LENGTH_SHORT).show();
return null;
}
}
}
return joinPoint.proceed();//Continue execution
}
/**
* Judge whether there is a network at present
*/
public boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
NetworkInfo[] infos = connectivityManager.getAllNetworkInfo();
if (infos != null && infos.length > 0) {
for (NetworkInfo info : infos) {
if (info.getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
public Context getContext(Object object) {
if (object instanceof Activity) {
return (Context) object;
} else if (object instanceof Fragment) {
return ((Fragment) object).getActivity();
} else if (object instanceof View) {
return ((View) object).getContext();
}
return null;
}
}
Just add the CheckNet method where you need to use it