Android—AspectJ实践
AspectJ支持編譯期和加載時(shí)代碼注入
Advice(通知):?典型的 Advice 類型有 before、after 和 around,分別表示在目標(biāo)方法執(zhí)行之前、執(zhí)行后和完全替代目標(biāo)方法執(zhí)行的代碼。
Joint point(連接點(diǎn)):?程序中可能作為代碼注入目標(biāo)的特定的點(diǎn)和入口。
Pointcut(切入點(diǎn)):?告訴代碼注入工具,在何處注入一段特定代碼的表達(dá)式。
Aspect(切面):?Pointcut 和 Advice 的組合看做切面。例如,在本例中通過定義一個(gè) pointcut 和給定恰當(dāng)?shù)腶dvice,添加一個(gè)了內(nèi)存緩存的切面。
Weaving(織入):?注入代碼(advices)到目標(biāo)位置(joint points)的過程。
AspectJ環(huán)境配置:
1.配置gradle
根項(xiàng)目gradle:
classpath 'org.aspectj:aspectjtools:1.8.9' classpath 'org.aspectj:aspectjweaver:1.8.9'AsepctJ項(xiàng)目:
api 'org.aspectj:aspectjrt:1.8.13'import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Mainandroid.libraryVariants.all { variant ->JavaCompile javaCompile = variant.javaCompilejavaCompile.doLast {String[] args = ["-showWeaveInfo","-1.5","-inpath", javaCompile.destinationDir.toString(),"-aspectpath", javaCompile.classpath.asPath,"-d", javaCompile.destinationDir.toString(),"-classpath", javaCompile.classpath.asPath,"-bootclasspath", android.bootClasspath.join(File.pathSeparator)]MessageHandler handler = new MessageHandler(true)new Main().run(args, handler)def log = project.loggerfor (IMessage message : handler.getMessages(null, true)) {switch (message.getKind()) {case IMessage.ABORT:case IMessage.ERROR:case IMessage.FAIL:log.error message.message, message.thrownbreakcase IMessage.WARNING:case IMessage.INFO:log.info message.message, message.thrownbreakcase IMessage.DEBUG:log.debug message.message, message.thrownbreak}}} }如果直接在app的gradle中配置
implementation 'org.aspectj:aspectjrt:1.8.13'import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Mainfinal def variants = project.android.applicationVariants variants.all { variant ->JavaCompile javaCompile = variant.javaCompilejavaCompile.doLast {String[] args = ["-showWeaveInfo","-1.5","-inpath", javaCompile.destinationDir.toString(),"-aspectpath", javaCompile.classpath.asPath,"-d", javaCompile.destinationDir.toString(),"-classpath", javaCompile.classpath.asPath,"-bootclasspath", android.bootClasspath.join(File.pathSeparator)]MessageHandler handler = new MessageHandler(true)new Main().run(args, handler)def log = project.loggerfor (IMessage message : handler.getMessages(null, true)) {switch (message.getKind()) {case IMessage.ABORT:case IMessage.ERROR:case IMessage.FAIL:log.error message.message, message.thrownbreakcase IMessage.WARNING:case IMessage.INFO:log.info message.message, message.thrownbreakcase IMessage.DEBUG:log.debug message.message, message.thrownbreak}}} }注意:在哪使用就需要在哪配置上面的一大段東西,網(wǎng)絡(luò)上也有自定義Puglin進(jìn)行組件化的操作,就不用每個(gè)都去設(shè)置,但是自己嘗試了報(bào)錯(cuò)。
2.MianActivity代碼
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv = findViewById(R.id.tv);tv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {showToast();}});}private void showToast(){Toast.makeText(MainActivity.this,"aaaaaaaaaaa",Toast.LENGTH_SHORT).show();} }3.調(diào)用AspectJ
@Aspect public class AspectJText {@Before("execution(* com.example.aspectjdemo.MainActivity.showToast(..))")public void show(JoinPoint joinPoint){Toast.makeText((Context) joinPoint.getThis(), "hhhhhh", Toast.LENGTH_SHORT).show();}final String TAG = AspectJText.class.getSimpleName();@Before("execution(* *..MainActivity+.on**(..))")public void method(JoinPoint joinPoint) throws Throwable {MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();String className = joinPoint.getThis().getClass().getSimpleName();Log.e(TAG, "class:" + className);Log.e(TAG, "method:" + methodSignature.getName());}}運(yùn)行結(jié)果:
?編譯后文件:
?可以看到編譯后的類文件出現(xiàn)了AspectJ動(dòng)態(tài)加上的語(yǔ)句。
總結(jié)
以上是生活随笔為你收集整理的Android—AspectJ实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【C/C++和指针】深度解析---指针与
- 下一篇: Android—热修复实践