AspectJ/AOP 在android上的实践小结

这编文章写的很详细,在此转载:
https://www.jianshu.com/p/f90e04bcb326

本文测试的效果图如下:
这里写图片描述

本文要当日记类,方便下次用到的时候用:


package com.haocai.aopdemo;

import android.Manifest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import java.text.SimpleDateFormat;

public class MainActivity extends AppCompatActivity {

    private int age;

    public int getAge() {
        return this.age;
    }

    /**--------------------在aspject中测试获取代码中的函数返回值-----------------*/
    public int getHeight() {
        return 0;
    }

    public int getHeight(int sex) {
        switch (sex) {
            case 0:
                return 163;
            case 1:
                return 173;
        }
        return 173;
    }
    /**--------------------end-----------------*/

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.age = 10;
        setContentView(R.layout.activity_main);
    }


    @BehaviorTrace(value = "摇一摇", type = 1)
    public void mShake(View view) {

    }


    //@BehaviorTrace(value = "语音:", type = 2)
    public void callMethod(View view) {
        testCallMethod();
    }


    public void testGet(View view) {
        System.out.println("39---------测试 aspectJ 中 修改属性方法,修改后的age:"+age);
    }


    private void testCallMethod(){
        System.out.println("38---------测试 aspectJ 中 call方法,这里是待测试的方法");

    }

    public void afterReturn(View view){
        getHeight(23);
    }


    @PermissonAnnotation(value = Manifest.permission.CAMERA)
    public void permisson(View view){
        System.out.println("72---------如果这段代码执行了,代表权限通过");

    }


}

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal">

        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="50dp"
            android:text="execution"
            android:onClick="mShake"
            android:gravity="center"
            android:layout_marginTop="20dp"
            />
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="50dp"
            android:text="call"
            android:onClick="callMethod"
            android:gravity="center"
            android:layout_marginTop="20dp"
            />
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="50dp"
            android:text="测试属性get"
            android:onClick="testGet"
            android:gravity="center"
            android:layout_marginTop="20dp"
            />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal">

        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="50dp"
            android:text="afterReturn"
            android:onClick="afterReturn"
            android:gravity="center"
            android:layout_marginTop="20dp"
            />
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="50dp"
            android:text="测试权限申请"
            android:onClick="permisson"
            android:gravity="center"
            android:layout_marginTop="20dp"
            />
        <!--<Button-->
            <!--android:layout_width="0dp"-->
            <!--android:layout_weight="1"-->
            <!--android:layout_height="50dp"-->
            <!--android:text="测试属性get"-->
            <!--android:onClick="testGet"-->
            <!--android:gravity="center"-->
            <!--android:layout_marginTop="20dp"-->
            <!--/>-->

    </LinearLayout>



</LinearLayout>

注解文件:

package com.haocai.aopdemo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


//ElementType.METHOD 用于描述方法
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BehaviorTrace {
    String value();
    int type();
}

注解文件二:

package com.haocai.aopdemo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by liuxiaobing on 2018/8/1.
 * 权限的 的 注解
 */

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PermissonAnnotation {
    String value();
}

aspectj文件:

package com.haocai.aopdemo;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.support.v4.content.ContextCompat;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

import java.text.SimpleDateFormat;

/**
 * Created by liuxiaobing on 2018/08/01.
 */
@Aspect
public class BehaviorAspect {
    private static final String TAG = "MainAspect";
    SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 测试切点,execution :函数执行内部
     *
     */
    @Pointcut("execution(@com.haocai.aopdemo.BehaviorTrace * *(..)) && @annotation(behaviorTrace)")
    public void annoBehavior(BehaviorTrace behaviorTrace) throws Throwable{

    }

    @Around("annoBehavior(behaviorTrace)")
    public Object dealPoint(ProceedingJoinPoint point,BehaviorTrace behaviorTrace) throws Throwable{

        Object result = null;
        result = point.proceed();
        System.out.println("34--------value:"+behaviorTrace.value());
        return result;
    }

    /**
     * 测试方法调用时,触发
     *
     * @Around 不能和 @Before、@After 一起使用,如果不小心这样用了,你会发现没有任何效果。
     * @Around 会替换原先执行的代码,但如果你仍然希望执行原先的代码,可以使用joinPoint.proceed()。
     */
    @Pointcut("call(* com.haocai.aopdemo.MainActivity.testCallMethod(..))")
    public void callMethod() {}

    @Before("callMethod()")
    public void beforeMethodCall(JoinPoint joinPoint) {
        System.out.println("45--------beforeMethodCall:"+joinPoint.getTarget().toString() + "#" + joinPoint.getSignature().getName());
    }

    /**
     * 测试 属性修改值
     * 测试例子:我们希望不管怎么修改age的值,最后获取的age都为100,那么就需要替换访问age的代码:
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("get(int com.haocai.aopdemo.MainActivity.age)")
    public int aroundFieldGet(ProceedingJoinPoint joinPoint) throws Throwable {
        // 执行原代码
        Object obj = joinPoint.proceed();
        int age = Integer.parseInt(obj.toString());
        System.out.println("59--------before age:"+age);
        return 100;
    }


    /**
     * 测试 获取代码中的 函数返回值,getHeight(..) 括号中的 ..表示任意类型
     * 如果 想限定 getHeight()括号中的形参类型,可以使用如下方式
     * 方式一:Pointcut 中表示任意参数的 .. 改为 int 即下述例子改为:
     * @AfterReturning(pointcut = "execution(* com.haocai.aopdemo.MainActivity.getHeight(int))", returning = "height")
     *
     * 方式二:
     * @AfterReturning(pointcut = "execution(* com.haocai.aopdemo.MainActivity.getHeight(..)) && args(int)", returning = "height")
     * @param height
     */
    @AfterReturning(pointcut = "execution(* com.haocai.aopdemo.MainActivity.getHeight(..))", returning = "height")
    public void getHeight(int height) {
        System.out.println("59--------height:"+height);
    }


    @Around("execution(@com.haocai.aopdemo.PermissonAnnotation * *(..)) && @annotation(permisson)")
    public void checkPermisson(final ProceedingJoinPoint joinPoint, PermissonAnnotation permisson) throws Throwable {

        String permissonStr = permisson.value();
        Activity mainActivity = (Activity) joinPoint.getThis();
        int check = ContextCompat.checkSelfPermission(mainActivity, permissonStr);
        if (check != PackageManager.PERMISSION_GRANTED) {
            System.out.println("96-------------未授权:"+permissonStr +" :程序停止");
        }else{
            System.out.println("102-------------已授权:"+permissonStr +" :程序将继续执行");
        }
    }


}

mainfesty:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.haocai.aopdemo">

    <uses-permission android:name="android.permission.CAMERA" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

猜你喜欢

转载自blog.csdn.net/d06110902002/article/details/81347485