Giter VIP home page Giter VIP logo

saf-aop's Introduction

SAF-AOP

@Tony沈哲 on weibo Download License

基于 Aspecj 实现的 Android AOP 框架,并使用沪江的gradle 插件:https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx

下载安装

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

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

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

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

...

dependencies {
    compile 'com.safframework:saf-aop:1.3.0'
    ...
}

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

注解名称 作用 备注
@Async 借助RxJava,异步地执行app中的方法
@Cacheable Spring Cache风格的Cache注解,将结果放于缓存中 只适用于android4.0以后
@LogMethod 将方法的入参和出参都打印出来,可以用于调试
@HookMethod 可以在调用某个方法之前、以及之后进行hook 比较适合埋点的场景,可以单独使用也可以跟任何自定义注解配合使用。也支持在匿名内部类中使用
@Prefs 将方法返回的结果放入AppPrefs中 只适用于android4.0以后
@Safe 可以安全地执行方法,而无需考虑是否会抛出运行时异常 支持在捕获异常的时候进行监听
@Trace 用于追踪某个方法花费的时间,可以用于性能调优的评判 支持追踪匿名内部类中的方法
@Permission 可用于运行时动态地申请权限

@Async的使用方法:

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

@Cacheable的使用方法:

	@Cacheable(key = "user")
	private User initData() {
		User user = new User();
		user.userName = "tony";
		user.password = "123456";
		return user;
	}

这里的@Cacheable,实际上用到Cache,要获取Cache也很简单.

@Trace的使用方法:

	@Trace
	@Async
	private void loadUser() {
		Log.e(TAG, " thread=" + Thread.currentThread().getId());
		Log.e(TAG, "ui thread=" + Looper.getMainLooper().getThread().getId());
		Cache cache = Cache.get(this);
		User user = (User) cache.getObject("user");
		Toast.makeText(MainActivity.this, SAFUtils.printObject(user), Toast.LENGTH_SHORT).show();
	}

将@Trace和@Async两个注解结合使用,可以看到调用loadUser()方法花费的时间.

05-18 14:31:31.229 21190-21190/app.magicwindow.cn.testsaf I/MainActivity: MainActivity=loadUser() take [1ms]
05-18 14:31:31.231 21190-22033/app.magicwindow.cn.testsaf E/com.test.saf.activity.MainActivity:  thread=14876
05-18 14:31:31.231 21190-22033/app.magicwindow.cn.testsaf E/com.test.saf.activity.MainActivity: ui thread=1

@Trace还支持在匿名内部类中使用

    @Trace
    private void initData() {

        Observable.create(new ObservableOnSubscribe<String>() {

            @Trace
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> e) throws Exception {

                e.onNext("111");
                e.onNext("222");
                e.onNext("333");

            }
        }).subscribe(new Consumer<String>() {

            @Trace
            @Override
            public void accept(@NonNull String str) throws Exception {

            }
        });
    }

@HookMethod的使用方法:

不写beforeMethod和afterMethod,则相当于没有使用@HookMethod
beforeMethod和afterMethod对应的都是方法名,分别表示在调用doSomething()之前执行和之后执行。目前还不支持在beforeMethod和afterMethod中传递参数。

   @HookMethod(beforeMethod="dosthbeforeMethod",afterMethod="dosthafterMethod")
   void doSomething() {

   }

@HookMethod 同样支持在匿名内部类中使用

    @HookMethod(beforeMethod = "method1",afterMethod = "method2")
    private void initData() {

        L.i("initData()");
    }

    private void method1() {
        L.i("method1() is called before initData()");
    }

    private void method2() {
        L.i("method2() is called after initData()");
    }

    private void testRx() {

        Observable.just("tony")
                .subscribe(new Consumer<String>() {

                    @HookMethod(beforeMethod = "testRxBefore")
                    @Override
                    public void accept(@NonNull String s) throws Exception {
                        System.out.println("s="+s);
                    }

                    private void testRxBefore() {
                        L.i("testRxBefore() is called before accept()");
                    }
                });

Proguard

-keep class com.safframework.aop.** { *; }

联系方式

Wechat:fengzhizi715

SAF-AOP相关文章:

http://www.jianshu.com/p/9e78560cadad

http://www.jianshu.com/p/2779e3bb1f14

Java与Android技术栈:每周更新推送原创技术文章,欢迎扫描下方的公众号二维码并关注,期待与您的共同成长和进步。

ChangeLog

版本更新记录

License

Copyright (C) 2017 - present, Tony Shen.

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

   http://www.apache.org/licenses/LICENSE-2.0

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.

saf-aop's People

Contributors

fengzhizi715 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

saf-aop's Issues

unexpected scopes found...

在根目录和module下的build.gradle添加了配置,编译的时候报错:
(gradle版本4.1 gradle pugin 3.0)
Error:Execution failed for task ':app:transformClassesWithDexBuilderForDebug'.

Unexpected scopes found in folder '/Users/shaochuankai/Documents/sck/aopdemo/app/build/intermediates/transforms/AspectTransform/debug'. Required: PROJECT, SUB_PROJECTS, EXTERNAL_LIBRARIES. Found: EXTERNAL_LIBRARIES, PROJECT, PROJECT_LOCAL_DEPS, SUB_PROJECTS, SUB_PROJECTS_LOCAL_DEPS

编译的你的项目,出现以下问题,帮忙看下问题原因 谢谢

15:22:33 Gradle build finished with 1 error(s) and 1 warning(s) in 34s 185ms
15:26:55 PluginException: jar://C:/Users/zhangtao-iri/Desktop/SAF-AOP-master/app/build/intermediates/exploded-aar/com.safframework.injectview/saf-injectview/1.0.0/jars/classes.jar!/com/safframework/injectview/Injector.class: stub:[]; mirror:[PsiParameter:$enum_name_or_ordinal$0, PsiParameter:$enum_name_or_ordinal$1] [Plugin: org.jetbrains.java.decompiler]

最新版本还是报错Unexpected scopes found in

java.lang.RuntimeException: Unexpected scopes found in folder 'G:\git\android_ck\lib\SAF-AOP\app\build\intermediates\transforms\AspectTransform\debug'. Required: SUB_PROJECTS. Found: EXTERNAL_LIBRARIES, PROJECT, SUB_PROJECTS

沪江的插件问题

你引用了沪江的插件,那么这个库能否支持 gradle7.x 织入环境多线程报错解决了没?

HookMethod能否将被hook的方法的传入参数一起hook住?

 private void testRx() {
        Observable.just("tony")
                .subscribe(new Consumer<String>() {
                    @HookMethod(beforeMethod = "testRxBefore")
                    @Override
                    public void accept(@NonNull String s) throws Exception {
                        System.out.println("s="+s);
                    }

                    private void testRxBefore() {
                        L.i("testRxBefore() is called before accept()");
                    }
                });

这个是HookMethod的例子,这里的testRxBefore有办法将accept(String s) 中的String s给hook住吗?
即testRxBefore()变成testRxBefore(String s),类似这样的.

能不能给@Safe加上监听呢

一旦报错可以在Appliacation后者一个全局的地方加上监听,比如发生报错我可以想友盟统计发送一个自定义异常,这样可以监听用户使用情况

NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;

gradle:3.2.0
使用 @safe时报错:
java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
at com.safframework.log.L.(L.kt:52)
at com.safframework.aop.SafeAspect.safeMethod(SafeAspect.java:34)
at com.safframework.aop.SafeAspect.ajc$inlineAccessMethod$com_safframework_aop_SafeAspect$com_safframework_aop_SafeAspect$safeMethod(SafeAspect.java:1)
at com.safframework.aop.SafeAspect.doSafeMethod(SafeAspect.java:21)

Caused by: java.lang.ClassNotFoundException: Didn't find class "kotlin.jvm.internal.Intrinsics" on path: DexPathList[[zip file "/data/app/com.bgi.supervision.explor-1/base.apk"],nativeLibraryDirectories=[/data/app/com.bgi.supervision.explor-1/lib/arm64, /vendor/lib64, /system/lib64]]

StopWatch

StopWatch 中的getTotalTimeMillis()可以考虑去掉ms单位转换,直接用微毫秒显示(或者XXmsXXμs)
毕竟大部分时候方法都是0ms但是大量次数运行也有优化的空间

NOClassDefFoundError错误

在项目中引进这个插件后,在activity的onCreate中进行hook,

  @HookMethod(beforeMethod = "foo")
    override fun onCreate(savedInstanceState: Bundle?) 

发生如下错误
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/safframework/tony/common/utils/Preconditions;
at com.safframework.aop.HookMethodAspect.hookMethod(HookMethodAspect.java:48)
at com.project.android.apps.gccm.FrameworkActivity.onCreate(FrameworkActivity.kt:131)

foo已经定义:

private fun foo(){
       Log.e("Test123", "empty input param")
   }

这个是什么原因造成的呢?不支持kotlin吗?

@safe

@safe 把所有代码都给try catch,导致效率降低。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.