All Projects → linisme → Crepecake

linisme / Crepecake

Licence: apache-2.0
An compile-time aop engine like AspectJ but easier to use in android application development.

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Crepecake

metrics-aspectj
AspectJ integration for Dropwizard Metrics
Stars: ✭ 78 (-24.27%)
Mutual labels:  aop, aspectj
Androidlearn
Android Custom Views
Stars: ✭ 66 (-35.92%)
Mutual labels:  aop, aspectj
Paonet
【MVVM+RxJava2+AspectJ】泡网第三方客户端,网站主页:http://www.jcodecraeer.com/index.php
Stars: ✭ 374 (+263.11%)
Mutual labels:  aop, aspectj
Fragmentrigger
💥A powerful library powered by AOP to manage Fragments.(一个基于AOP设计的Fragment管理框架)
Stars: ✭ 2,260 (+2094.17%)
Mutual labels:  aop, aspectj
android-aop-analytics
Demo application that implements Google Analytics tracking in an aspect-oriented way using AspectJ.
Stars: ✭ 31 (-69.9%)
Mutual labels:  aop, aspectj
T Mvp
Android AOP Architecture by Apt, AspectJ, Javassisit, based on Realm+Databinding+MVP+Retrofit+Rxjava2
Stars: ✭ 2,740 (+2560.19%)
Mutual labels:  aop, aspectj
Automon
Automon combines the power of AOP (AspectJ) with monitoring or logging tools you already use to declaratively monitor your Java code, the JDK, and 3rd party libraries.
Stars: ✭ 548 (+432.04%)
Mutual labels:  aop, aspectj
Ray.aop
An aspect-oriented framework for PHP
Stars: ✭ 67 (-34.95%)
Mutual labels:  aop
Postsharp.samples
PostSharp Samples
Stars: ✭ 84 (-18.45%)
Mutual labels:  aop
Spring Examples
SpringBoot Examples
Stars: ✭ 67 (-34.95%)
Mutual labels:  aop
Goaop Symfony Bundle
[Outdated!] Integration bridge for Go! AOP framework and Symfony
Stars: ✭ 59 (-42.72%)
Mutual labels:  aop
Koatty
Koa2 + Typescript = Koatty. Use Typescript's decorator implement IOC and AOP.
Stars: ✭ 67 (-34.95%)
Mutual labels:  aop
Jeeplatform
一款企业信息化开发基础平台,拟集成OA(办公自动化)、CMS(内容管理系统)等企业系统的通用业务功能 JeePlatform项目是一款以SpringBoot为核心框架,集ORM框架Mybatis,Web层框架SpringMVC和多种开源组件框架而成的一款通用基础平台,代码已经捐赠给开源中国社区
Stars: ✭ 1,285 (+1147.57%)
Mutual labels:  aop
Swifthook
A library to hook methods in Swift and Objective-C.
Stars: ✭ 93 (-9.71%)
Mutual labels:  aop
Laravel Aspect
aspect oriented programming Package for laravel framework
Stars: ✭ 98 (-4.85%)
Mutual labels:  aop
Aspectcore Framework
AspectCore is an AOP-based cross platform framework for .NET Standard.
Stars: ✭ 1,318 (+1179.61%)
Mutual labels:  aop
Lithium
li₃ is the fast, flexible and most RAD development framework for PHP
Stars: ✭ 1,176 (+1041.75%)
Mutual labels:  aop
Eshop Soa
EShop基于Dubbo实现SOA服务化拆分,并基于RocketMQ解决了分布式事务(新版SpringBootSOASkeleton)
Stars: ✭ 65 (-36.89%)
Mutual labels:  aop
Sandhook
Android ART Hook/Native Inline Hook/Single Instruction Hook - support 4.4 - 11.0 32/64 bit - Xposed API Compat
Stars: ✭ 1,172 (+1037.86%)
Mutual labels:  aop
Python Aspectlib
An aspect-oriented programming, monkey-patch and decorators library. It is useful when changing behavior in existing code is desired. It includes tools for debugging and testing: simple mock/record and a complete capture/replay framework.
Stars: ✭ 90 (-12.62%)
Mutual labels:  aop

CrepeCake

A compile-time aop engine like AspectJ but easier to use in android application development.

GitHub license Android Weekly Recommend

Wiki


First At A Glance : ]

Here is am example that injected the onCreate() Method in MainActivity:


@Aspect(MainActivity.class)
public class MainActivityAspect {

    protected void onCreate(InvocationHandler invocationHandler, Bundle savedInstanceState) {
      System.out.println("⇢ onCreate");
      long startTime = System.currentTimeMillis();
      invocationHandler.invoke(savedInstanceState);
      System.out.println(String.format("⇠ onCreate [%dms]", System.currentTimeMillis() - startTime));    
    }

}

That's all,these code will be executed during the onCreate method in MainActivity with printing the running time of it:

I/System.out: ⇢ onCreate
I/System.out: ⇠ onCreate [33ms]

Installation

  1. Add the buildscript dependencies in the root project:
buildscript {

  repositories {
      google()
      jcenter()
  }
  dependencies {
      classpath 'com.android.tools.build:gradle:3.0.1'
      classpath 'net.idik.crepecake:plugin:0.0.4' // Add Here
  }

}
  1. Add crepecake plugin in the target module

The crepecake plugin MUST AFTER(VERY IMPORTANT) the application plugin


// Apply application or library plugin here...
apply plugin: 'net.idik.crepecake'

Usage

  1. Programme the injection processor on the basis of target class, with the annotation @Aspect
@Aspect(MainActivity.class)
public class MainActivityAspect {
  // injection methods...
}
  1. Programme the injection method

    Step 1. Declare the injection method with the target method infos, including the access level, static or not, name of method, parameters.

    Step 2. Insert InvocationHandler invocationHandler at the 1st position of the parameter list

    Done.

    @Aspect(MainActivity.class)
    public class MainActivityAspect {
    
        protected void onCreate(InvocationHandler invocationHandler, Bundle savedInstanceState) {
          System.out.println("⇢ onCreate");
          long startTime = System.currentTimeMillis();
          invocationHandler.invoke(savedInstanceState);
          System.out.println(String.format("⇠ onCreate [%dms]", System.currentTimeMillis() - startTime)); 
        }
    
        public android.support.v7.app.ActionBar getSupportActionBar(InvocationHandler invocationHandler) {
            ActionBar bar = (ActionBar) invocationHandler.invoke();
            //do stuff...
            return bar;
        }
    
        //other injection methods...
    }
    

So far, we have completed the job that injects the onCreate(Bundle savedInstanceState)getSupportActionBar() and other methods in the MainActivity.

InvocationHandler is a flag indicating this is an injection method. Beside, we could invoke the original method through it and obtain the result(if return type is not void).

AspectConfig

We could customize the injection points by inheriting the AspectConfig class

public class OnClickAspectConfig extends AspectConfig {
    @Override
    protected boolean isEnable() {
        return super.isEnable();
    }

    @Override
    public boolean isHook(Class clazz) {
        return View.OnLongClickListener.class.isAssignableFrom(clazz) || View.OnClickListener.class.isAssignableFrom(clazz);
    }
}

The above codes means that we will inject ALL the subClass of OnLongClickListener and OnClickListener.

⚠️ Attention: The AspectConfig class will be executed during the compile-time, so do not make any running-time logic within it.

Then, use it to the injection processor with the annotation @Aspect

@Aspect(OnClickAspectConfig.class)
public class OnClickListenerAspect {
  public void onClick(InvocationHandler invocationHandler, View view) {
      System.out.println("OnClick: " + view);
      invocationHandler.invoke(view);
  }

  public boolean onLongClick(InvocationHandler invocationHandler, View view) {
      boolean isConsume = (boolean) invocationHandler.invoke(view);
      if (isConsume) {
          System.out.println("OnLongClick: " + view);
      }
      return isConsume;
  }
}

See more...

Great Thanks to...


先撇一眼 : ]

举个例子注入MainActivity的onCreate方法:


@Aspect(MainActivity.class)
public class MainActivityAspect {

    protected void onCreate(InvocationHandler invocationHandler, Bundle savedInstanceState) {
      System.out.println("⇢ onCreate");
      long startTime = System.currentTimeMillis();
      invocationHandler.invoke(savedInstanceState);
      System.out.println(String.format("⇠ onCreate [%dms]", System.currentTimeMillis() - startTime));    
    }

}

这就完成了对MainActivity的注入,以上代码会输出onCreate的运行时间:

I/System.out: ⇢ onCreate
I/System.out: ⇠ onCreate [33ms]

安装

  1. 在root project的buildscript中添加dependencies如下:
buildscript {

  repositories {
      google()
      jcenter()
  }
  dependencies {
      classpath 'com.android.tools.build:gradle:3.0.1'
      classpath 'net.idik.crepecake:plugin:0.0.4' //添加在此
  }

}
  1. 在目标模块的build.gradle文件中添加插件(请务必添加于Application插件后)如下:
// apply application or library plugin here
apply plugin: 'net.idik.crepecake'

用法

  1. 根据目标类,编写注入处理器,通过@Aspect指定目标类
@Aspect(MainActivity.class)
public class MainActivityAspect {
  // 注入方法们...
}
  1. 编写注入方法,步骤如下

    Step 1. 声明注入方法与目标方法声明一致,包括访问属性、静态、方法命名、参数列表等
    Step 2. 添加InvocationHandler invocationHandler至参数列表第一位
    Done.

    @Aspect(MainActivity.class)
    public class MainActivityAspect {
    
        protected void onCreate(InvocationHandler invocationHandler, Bundle savedInstanceState) {
          System.out.println("⇢ onCreate");
          long startTime = System.currentTimeMillis();
          invocationHandler.invoke(savedInstanceState);
          System.out.println(String.format("⇠ onCreate [%dms]", System.currentTimeMillis() - startTime));
        }
    
        public android.support.v7.app.ActionBar getSupportActionBar(InvocationHandler invocationHandler) {
            ActionBar bar = (ActionBar) invocationHandler.invoke();
            //do stuff...
            return bar;
        }
    
        //other inject methods...
    }
    

至此,我们已经完成了对MainActivity的onCreate(Bundle savedInstanceState)getSupportActionBar()以及其他方法的切面注入。

InvocationHandler这个参数很重要,这个参数标志着这是一个注入方法,并且通过这个参数,我们可以调用目标方法,并获取返回值(如果非void

AspectConfig

通过继承AspectConfig对象可以对注入点进行个性化的定制,如下:

public class OnClickAspectConfig extends AspectConfig {
    @Override
    protected boolean isEnable() {
        return super.isEnable();
    }

    @Override
    public boolean isHook(Class clazz) {
        return View.OnLongClickListener.class.isAssignableFrom(clazz) || View.OnClickListener.class.isAssignableFrom(clazz);
    }
}

其中,isHook方法判断该类是否为目标类,在上述代码中指定了OnLongClickListenerOnClickListener所有子类都为注入目标,我们可以通过该方法进行定制。

⚠️ 注意:这个类将会在编译时被调用,请不要在此类中做运行时动态逻辑。

写完配置类后,在注入类上通过@Aspect注解应用即可

@Aspect(OnClickAspectConfig.class)
public class OnClickListenerAspect {
  public void onClick(InvocationHandler invocationHandler, View view) {
      System.out.println("OnClick: " + view);
      invocationHandler.invoke(view);
  }

  public boolean onLongClick(InvocationHandler invocationHandler, View view) {
      boolean isConsume = (boolean) invocationHandler.invoke(view);
      if (isConsume) {
          System.out.println("OnLongClick: " + view);
      }
      return isConsume;
  }
}

查看更多...

万分感谢


License

Copyright 2017 认真的帅斌

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].