美文网首页架构师之路
5. yyds Android 抖音头条网络统一处理AOP Aj

5. yyds Android 抖音头条网络统一处理AOP Aj

作者: 鹏城十八少 | 来源:发表于2021-12-27 21:08 被阅读0次

中级程序员的写法

     /**
     * 跳转到待收货页面
     */
    public void jumpWaitReceiving() {
        // 判断当前有没有网络
        if(CheckNetUtil.isNetworkAvailable(this)) {
            // 当前有网络我才跳转,进入待收货页面
            Intent intent = new Intent(this, WaitReceivingActivity.class);
            startActivity(intent);
        }
    }

    /**
     * 跳转到我的钱包页面
     */
    public void jumpMineWallet() {
        if(CheckNetUtil.isNetworkAvailable(this)) {
            Intent intent = new Intent(this, MineWalletActivity.class);
            startActivity(intent);
        }
    }

高级程序员的写法

通过一行注解实现

    /**
    * 跳转到待收货页面
    */
    @CheckNet
    public void jumpWaitReceiving() {
        Intent intent = new Intent(this, WaitReceivingActivity.class);
        startActivity(intent);
    }

    /**
     * 跳转到我的钱包页面
     */
    @CheckNet
    public void jumpMineWallet() {
        Intent intent = new Intent(this, MineWalletActivity.class);
        startActivity(intent);
    }

AOP

全称“Aspect Oriented Programming”,面向切面编程,由于面向对象的思想要求高内聚,低耦合的风格,使模块代码间的可见性变差,对于埋点,日志输出等需求,就会变的十分复杂,如果手动编写代码,入侵性很大,不利于扩展,AOP应运而生

二、使用场景

当我们需要在某个方法运行前和运行后做一些处理时,便可使用AOP技术。具体有:

  • 统计埋点
  • 日志打印/打点
  • 数据校验
  • 行为拦截
  • 性能监控
  • 动态权限控制

AOP使用场景


1>:动态代理:比如MVP里面的 每次都要判断 M层是否为空;
2>:比如我们经常在Application中做一些 Activity的生命周期的监听;
3>:基于第三方的一些编译工具 AspectJ

实现原理:

不是用系统的编译器,用di san fAjpectJ的编译器

实现步骤:

第一步:添加AspectJ依赖

根目录下

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">classpath 'org.aspectj:aspectjtools:1.8.9' classpath 'org.aspectj:aspectjweaver:1.8.9'</pre>

项目下:

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem;">implementation 'org.aspectj:aspectjrt:1.8.13'</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">第二步: 定义注解 </pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">第二三:</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">切点:从那个入口</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">切面:切点之后会形成切面</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">具体:</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">1.获取注解</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">2.是否有网络</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">3.没有网络返回</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">注意:如何获取context?如何获取方法签名?</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;">为什么要获取函数的签名?
</pre>

<pre style="margin: 8px 0px; background-color: rgb(43, 43, 43); color: rgb(169, 183, 198); font-family: "JetBrains Mono", monospace; font-size: 0.817rem; text-align: left;"> <pre style="margin: 8px 0px; font-family: "JetBrains Mono", monospace;">/**

  • Created by peng on 2021/12/27. * 处理网络检测切面 */ @Aspect public class SectionAspect {

    /**

  • 找到处理的切点 * 因为有一个项目可以有多个切点 * * *(..) 可以处理所有的方法 */ @Pointcut("execution(@com.example.gavin.apttest.CheckNet * *(..))")
    public void checkNetBehavior() {

    }

    /**

  • 处理切面 * 就是上面的方法checkNetBehavior() */ @Around("checkNetBehavior()")
    public Object checkNet(ProceedingJoinPoint joinPoint) throws Throwable {
    Log.e("TAG", "checkNet");
    // 做埋点 日志上传 权限检测, 网络检测
    // 网络检测 // 1.获取 CheckNet 注解 NDK 图片压缩 C++ 调用Java 方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法的签名
    CheckNet checkNet = signature.getMethod().getAnnotation(CheckNet.class);
    if (checkNet != null) {
    // 2.判断有没有网络 怎么样获取 context? //获取context,通过getThis()
    Object object = joinPoint.getThis();// View Activity Fragment ; getThis() 当前切点方法所在的类
    Context context = getContext(object);
    if (context != null) {
    if (!isNetworkAvailable(context)) {
    // 3.没有网络不要往下执行
    Toast.makeText(context,"请检查您的网络",Toast.LENGTH_LONG).show();
    return null; }
    }
    }
    return joinPoint.proceed(); //调用proceed,和ASM一样
    }

    /**

  • 通过对象获取上下文 * * @param object

  • @return
    */
    private Context getContext(Object object) {
    if (object instanceof Activity) {
    return (Activity) object;
    } else if (object instanceof Fragment) {
    Fragment fragment = (Fragment) object;
    return fragment.getActivity();
    } else if (object instanceof View) {
    View view = (View) object;
    return view.getContext();
    }
    return null;
    }

    /**

  • 检查当前网络是否可用 * * @return
    */
    private static boolean isNetworkAvailable(Context context) {
    // 获取手机所有连接管理对象(包括对wi-fi,net等连接的管理)
    ConnectivityManager connectivityManager = (ConnectivityManager)
    context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
    // 获取NetworkInfo对象
    NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo(); if (networkInfo != null && networkInfo.length > 0) {
    for (int i = 0; i < networkInfo.length; i++) {
    // 判断当前网络状态是否为连接状态
    if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED) {
    return true;
    }
    }
    }
    }
    return false;
    }
    }</pre> </pre>

相关文章

网友评论

    本文标题:5. yyds Android 抖音头条网络统一处理AOP Aj

    本文链接:https://www.haomeiwen.com/subject/qyquqrtx.html