This issue recommends XAOP, a lightweight AOP(Android) application framework.
In our usual development process, we must encounter problems such as permission application, thread switching, data cache, exception capture, buried point and method execution time statistics. These are very common problems, and it is not difficult to implement, but it is too cumbersome, and it will make the program a lot of repetitive, modular code. The development efficiency of typical application scenarios is greatly improved with XAOP’s section-oriented programming idea.
Features
- Support quick click slice @SingleClick, support to set the quick click interval.
- Support dynamic application for permission slicing @Permission, support custom response actions.
- Support for main thread slicing @MainThread.
- Supports IO thread slicing @IOThread and supports multiple thread pool types.
- Support log print slice @DebugLog, support custom logging mode.
- Support for MemoryCache slices@memorycache, support for setting the cache size.
- Support disk cache slicing @DiskCache, support custom disk cache, cache validity time, etc.
- Support for automatic exception capture interception slicing @Safe, support for setting custom exception handlers.
- Support custom intercept slicing @Intercept, support custom intercept slicing.
- Compatible with Kotlin syntax.
- Support androidx.
How to use
1 Add Gradle dependency
First add:
to build.gradle repositories in the project root directory
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Add the xaop plug-in to build.gradle’s dependencies in the project root directory:
buildscript {
···
dependencies {
···
classpath 'com.github.xuexiangjys.XAOP:xaop-plugin:1.1.0'
}
}
Add a dependency and reference to the xaop plugin in the build.gradle of your application project (typically an app) :
apply plugin: 'com.xuexiang.xaop' //Reference the xaop plug-in
dependencies {
···
//For Android X projects, use version 1.1.0 and above
implementation 'com.github.xuexiangjys.XAOP:xaop-runtime:1.1.0'
//For a support project, use version 1.0.5
implementation 'com.github.xuexiangjys.XAOP:xaop-runtime:1.0.5'
}
Initialize in Application:
XAOP.init(this); // initializes the plugin
XAOP.debug(true); // Enable
XAOP.setPriority(log.info) for Log printing slices; // Set the log printing level. The default value is 0
//Set dynamic application rights slice. Listen to the event that the application permission is denied
XAOP.setOnPermissionDeniedListener(new PermissionUtils.OnPermissionDeniedListener() {
@Override
public void onDenied(List<String> permissionsDenied) {
//Application permission denied processing
}
});
//Set the processing interceptor for custom intercepting slices
XAOP.setInterceptor(new Interceptor() {
@Override
public boolean intercept(int type, JoinPoint joinPoint) throws Throwable {
XLogger.d("Intercept in progress. Intercept type:" + type);
switch(type) {
case 1:
//Make the intercept you want
break;
case 2:
return true; //return true,Directly blocks slice execution
default:
break;
}
return false;
}
});
//Set the handler to automatically catch exceptions
XAOP.setIThrowableHandler(new IThrowableHandler() {
@Override
public Object handleThrowable(String flag, Throwable throwable) {
XLogger.d("The exception is caught. The flag of the exception is caught:" + flag);
if (flag.equals(TRY_CATCH_KEY)) {
return 100;
}
return null;
}
});
2 Compatible with Kotlin syntax configuration
Add the aspectjx plug-in to build.gradle’s dependencies in the project root directory:
buildscript {
···
dependencies {
···
classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10'
}
}
Add a dependency and reference to the aspectjx plug-in in the build.gradle of an application project (typically an app)
}apply plugin: 'android-aspectjx' //Reference the aspectjx plug-in
aspectjx {
include 'Project'sapplicationId'
}
Slice use
Quickly click slice using
1. Use @SingleClick to mark the click method. Note that the click method must have the click control View as the method parameter, otherwise it will not work.
2, you can set the quick click interval, the unit :ms. If this parameter is not set, the default value is 1000ms.
@SingleClick(5000)
public void handleOnClick(View v) {
XLogger.e("Click to respond!");
ToastUtil.get().toast("Click to respond!");
hello("xuexiangjys", "666666");
}
Dynamically apply for permission to slice use
1. Use @Permission to mark the method that requires permission to execute. You can apply for one or more permissions.
2. Using the @Permission annotation method, it will automatically determine whether it needs to apply for permission during execution.
@SingleClick
@Permission({PermissionConsts.CALENDAR, PermissionConsts.CAMERA, PermissionConsts.LOCATION})
private void handleRequestPermission(View v) {
}
Main thread slicing use
1. Use @MainThread to mark the methods that need to be executed in the main thread.
2. Using the @MainThread annotation method, it will automatically switch to the main thread when executed.
@MainThread
private void doInMainThread(View v) {
mTvHello.setText("Works on the main thread");
}
IO thread slicing use
1. Use @IOThread to mark the method that needs to be executed in the io thread. The thread pool type can be set to ThreadType. If it is not set, the default type is Fixed.
The types of thread pools are as follows :
-
- Single: single thread pool
- Fixed: multithreaded pool
- Disk: disk read-write thread pool (essentially a single-thread pool)
- Network: network request thread pool (essentially multi-threaded pool)
2. Use the @IOThread annotation method to automatically switch to the specified type of io thread during execution.
@IOThread(ThreadType.Single)
private String doInIOThread(View v) {
return "io线程名:" + Thread.currentThread().getName();
}
Log print slice Use
1. Use @DebugLog to mark the methods and classes that need to be printed. The printing priority can be set. If it is not set, the default priority is 0. Note: If the print priority is lower than the priority set by XAOP.setPriority, it will not be printed.
2, the class and method marked with @DebugLog will be printed in the process of execution, the method name, parameters, execution time, and result will be printed.
3, you can call XAOP.setISerializer to set the serializer of the serialized parameter object when printing.
4, you can call XAOP.setLogger to set the implementation interface for printing. By default, logcat logs that exceed the 4000 limit are printed.
@DebugLog(priority = Log.ERROR)
private String hello(String name, String cardId) {
return "hello, " + name + "! Your CardId is " + cardId + ".";
}
Memory cache slicing
1. Use @MemoryCache to mark the methods that require memory caching. If the cache key is not specified, the method name is the default key. (Parameter 1 = parameter 1 value | Parameter 2 = parameter 2 value |…) Of course, you can also modify the automatic key generation rule, you just need to call XAOP.setICacheKeyCreator can be done.
2, the annotated method must have a return value, otherwise the memory cache slicing will not work.
3. Using the @MemoryCache annotation method, the cache policy can be automatically implemented. The default memory cache used is LruCache.
4, can call XAOP.initMemoryCache to set the maximum number of memory cache. The default is Runtime.getRuntime().maxMemory() / 1024) / 8
@MemoryCache
private String hello(String name, String cardId) {
return "hello, " + name + "! Your CardId is " + cardId + ".";
}
Disk cache slicing
1. Use @DiskCache to mark the method that requires disk cache. If the cache key is not specified, the method name is the default key. (Parameter 1 = parameter 1 value | Parameter 2 = parameter 2 value |…) Of course, you can also modify the automatic key generation rule, you just need to call XAOP.setICacheKeyCreator can be done.
2, you can set the validity period of disk cache, unit :s. If this parameter is not set, the default is permanent.
3, the annotated method must have a return value, otherwise the disk cache slicing will not work.
4. Using the @DiskCache annotation method, the cache policy can be automatically implemented. The default disk cache used is JakeWharton’s DiskLruCache.
5, can call XAOP.initDiskCache set disk cache attributes, including disk serializer IDiskConverter, disk cache root directory, disk cache maximum space, etc.
@DiskCache
private String hello(String name, String cardId) {
return "hello, " + name + "! Your CardId is " + cardId + ".";
}
Automatically capture abnormal slices using
1. Use @Safe to mark the methods that need to be used to catch exceptions. You can set a Flag for catching exceptions. The default Flag is the name of the current class. Method name.
< p data – track = “88” > 2, call XAOP. SetIThrowableHandler set an exception of custom processing, can realize to offset processing of the exception. If not set, only the exception stack information is printed.
3. Using the @Safe annotation method, the exception can be automatically captured and handled in a unified manner to ensure the smooth execution of the method.
@Safe(TRY_CATCH_KEY)
private int getNumber() {
return 100 / 0;
}
Custom block slice using
1. Use @Intercept to mark the methods and classes that need to be intercepted. One or more interception types can be set.
2. Custom intercepting slicing will not work if you do not call XAOP.setInterceptor to set the interceptor for slicing intercepting.
3. Classes and methods annotated with @Intercept will automatically invoke the interceptor set by XAOP for interception processing when executed. If the interceptor processing returns true, the execution of the class or method is intercepted and not executed.
4, using @Intercept can be flexible slice interception. Such as user login rights.
@SingleClick(5000)
@DebugLog(priority = Log.ERROR)
@Intercept(3)
public void handleOnClick(View v) {
XLogger.e("Click response!");
ToastUtil.get().toast("Click response!");
hello("xuexiangjys", "666666");
}
@DebugLog(priority = Log.ERROR)
@Intercept({1,2,3})
private String hello(String name, String cardId) {
return "hello, " + name + "! Your CardId is " + cardId + ".";
}
[Note] : When there are multiple slice annotations, they are generally executed in order from top to bottom.
—END—
Open Source protocol: Apache-2.0