安卓使用 AspectJ 项目,已经实现:异步线程执行方法;安全执行方法,记录方法执行时间,入参出参等;

720 阅读3分钟
原文链接: github.com

Jet AOP

License Download Github file size

AOP是OOP的延续,是软件开发中的一个热点,也是spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

Jet-AOP框架;虽然xposed,dexposed非常强大,但由于Android的碎片化比较严重,兼容问题永远是一座无法逾越的大山. 因此考虑用AspectJ来实现;

参考的主要项目代码为JakeWharton大神的Hugo。Hugo是一个非常容易使用、易扩展的Aop例子

更重要的是你可以 实现 任何AOP(面向切面)的代码。具体的实现参考 AspectJ 功能;

www.eclipse.org/aspectj/

logo

Fetures

  • 重复的功能,可以通过切面的方法来实现;

部分已实现的功能 Use

注解名称 作用 备注
@JThread 借助rxjava,异步执行app中的方法
@JLogMethod 将方法的入参和出参都打印出来,可以用于调试
@JTryCatch 可以安全地执行方法,而无需考虑是否会抛出运行时异常
@JLogTime 用于追踪某个方法花费的时间,可以用于性能调优的评判

@JThread的使用方法:

	@JThread
	private void useAsync() {
		Log.e(TAG, " thread=" + Thread.currentThread().getId());
		Log.e(TAG, "ui thread=" + Looper.getMainLooper().getThread().getId());
	}

@JLogMethod 等;

@JTryCatch
@JLogTime
@JLogMethod
public int testLog(int k) {
    int i = k + 100;
    int j = i++;
    j=j/0;
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return j;
}

LogCat 打印:

 MainActivity.testLog(..) 方法参数 : [10]
 MainActivity.testLog(..) 方法 返回值 : 0
 MainActivity.testLog 执行时间: [3ms]

AspectJ 实现 无侵入方法监控例子(View.onClick方法拦截)

无侵入方法监控例子

Download

在根目录下的build.gradle中添加

buildscript {
     repositories {
         jcenter()
     }
     dependencies {
         classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:1.0.8'
     }
 }

在app 模块目录下的build.gradle中添加

apply plugin: 'com.hujiang.android-aspectjx'

...

dependencies {
    compile 'com.meiyou.framework:jet-aop:0.0.1'
    ...
}

基于aspectj的AOP,无需使用耗费性能的反射.不过,需要在build.gradle中配置一下aspectj

待实现,

待实现区域,列了一些我想到的通用功能, 但是项目里面肯定还存在很多通用的功能;欢迎 各位 提Issue,让项目更强大;

  • @JPermission([int[]]) 方法需要的申请的权限数组; 比如:
      String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
  • @JAuthorize() 方法是否需要登录才能调用,否则跳到登录页面; 更强大的方式可以参考 Apache Shiro

Problem

  • Android Studio的Instant Run功能有时会对你的编译有影响,当出现这种情况时,关闭Instant Run功能,
  • aspectj代码编译时会报一些如下的错,找到对应的库,把这个库过滤掉就可以了。

aspectjx配置

aspectjx默认会遍历项目编译后所有的.class文件和依赖的第三方库去查找符合织入条件的切点,为了提升编译效率,可以加入过滤条件指定遍历某些库或者不遍历某些库。

includeJarFilterexcludeJarFilter可以支持groupId过滤,artifactId过滤,或者依赖路径匹配过滤

aspectjx {
	//织入遍历符合条件的库
	includeJarFilter 'universal-image-loader', 'AspectJX-Demo/library'
	//排除包含‘universal-image-loader’的库
	excludeJarFilter 'universal-image-loader'
}

. 忽略groupId为org.apache.httpcomponents的库

aspectjx {
	excludeJarFilter 'org.apache.httpcomponents'
}

. 忽略artifactId为gson的库

	aspectjx {
		excludeJarFilter 'gson'
	}

. 忽略jar alisdk-tlog-1.jar

	aspectjx {
		excludeJarFilter 'alisdk-tlog-1'
	}
  • 忽略所有依赖的库
aspectjx {
	excludeJarFilter '.jar'
}

参考

License


Copyright 2017 zhengxiaobin@xiaoyouzi.com 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 www.apache.org/licenses/LI… 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.