Android(安卓)引入AspectJ的记录
16lz
2021-12-04
Android 引入 AspectJ进行AOP开发的记录。
在不试用插件时,引入AspectJ到android工程
1. 在项目gradle引入插件:
dependencies { ... classpath 'org.aspectj:aspectjtools:1.9.5' ... }
2. 在创建aspect文件的包引入
dependencies { ... implementation 'org.aspectj:aspectjrt:1.9.5' ...}
并在同gradle文件中,加入
import org.aspectj.bridge.IMessageimport org.aspectj.bridge.MessageHandlerimport org.aspectj.tools.ajc.Mainfinal def log = project.loggerfinal def variants = project.android.applicationVariantsvariants.all { variant -> JavaCompile javaCompile if (variant.hasProperty('javaCompileProvider')) { //android gradle 3.3.0 + javaCompile = variant.javaCompileProvider.get() } else { javaCompile = variant.javaCompile } def buildType = variant.buildType.name javaCompile.doLast { MessageHandler handler = new MessageHandler(true) String[] javaArgs = [ "-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) ] new Main().run(javaArgs, handler) String[] kotlinArgs = [ "-showWeaveInfo", "-1.8", "-inpath", project.buildDir.path + "/tmp/kotlin-classes/" + buildType, "-aspectpath", javaCompile.classpath.asPath, "-d", project.buildDir.path + "/tmp/kotlin-classes/" + buildType, "-classpath", javaCompile.classpath.asPath, "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator) ] new Main().run(kotlinArgs, 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: case IMessage.INFO: log.info message.message, message.thrown break case IMessage.DEBUG: log.debug message.message, message.thrown break } } }}
这样就成功引入AspectJ工具了,下一步编写Aspect文件。
3. 先实现自己的业务逻辑
package com.example.cheng.test;import android.annotation.SuppressLint;import android.os.Bundle;import android.widget.TextView;import com.example.common.DisplayMetricsUtil;import androidx.annotation.Nullable;import androidx.appcompat.app.AppCompatActivity;public class MainActivityJava extends AppCompatActivity { @SuppressLint("SetTextI18n") @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView text = findViewById(R.id.text); text.measure(0, 0); text.setText("text width: " + DisplayMetricsUtil.px2dp(this, text.getMeasuredWidth())); }}
4. 再在同module下实现aspect文件
package com.example.cheng.test;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;@Aspectpublic class MainActivityAspectJava extends BaseAspect { @Pointcut("execution(* com.example.cheng.test.MainActivityJava.on*(..))") public void mainPointCut() { } @After("mainPointCut()") public void hookMain(JoinPoint joinPoint) throws Throwable { log("java::" + joinPoint.getSignature().toLongString()); } @Pointcut("call(* com.example.common.DisplayMetricsUtil.*(..))") public void displayPointCut() { } @After("displayPointCut()") public void hookDisplay(JoinPoint joinPoint) throws Throwable { log("java::" + joinPoint.getSignature().toLongString()); }}
输出效果:
补充记录:
1. 因为kotlin文件编译出的.class文件路径与java不同,所以需要额外为aspect tool指定kotlin的路径。
String[] kotlinArgs = [ "-showWeaveInfo", "-1.8", "-inpath", project.buildDir.path + "/tmp/kotlin-classes/" + buildType, "-aspectpath", javaCompile.classpath.asPath, "-d", project.buildDir.path + "/tmp/kotlin-classes/" + buildType, "-classpath", javaCompile.classpath.asPath, "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator) ] new Main().run(kotlinArgs, handler)
待解决问题:
1. kotlin每次都需要clean build
2. 如何跨module实现aop weave,即在一个包中,可以通过pointcut切入其他module中的方法及其调用。
3. Java写的业务逻辑,kotlin的aspect文件能够对其织入;Kotlin写的业务逻辑,Java的Aspect文件不能对其织入。
更多相关文章
- Android编译环境
- 关于Android的prelink(Linux)
- Fedora 15下使用android ndk 编译ffmepg0.8.4
- android 学习笔记1
- Android处理9.png文件流程
- Android的多媒体框架OpenCore(PacketVideo)介绍
- Cordova 3.x 基础(13) -- 为Android(安卓)APK签名
- Android更新ADT到R17以后,不能用第三方jar包了
- 在android真机上使用sqlite3