Android基于方法池与回调实现登录拦截的场景

目录
  • 前言
  • 一、使用通知与回调
  • 二、使用方法池
  • 总结

前言

前面的文章我们讲到APP登录拦截的功能实现,现在网上比较多的推荐使用AOP,我们使用下来还是太麻烦,兼容性问题很多,(坑太多,项目我已经改回来了,如果想体验AOP可以切换aop分支运行)

难道就想实现一个这么简单的功能,就非得使用AOP了吗?有没有简单一点的方式,方式其实太多了,个人感觉的话,完全没必要为了这么个小功能导入一个AOP库。今天我们看看使用方法池与通知回调的方式来处理登录拦截的逻辑。

一、使用通知与回调

其实本质逻辑就是想判断用户是否已经登录,然后跳转到登录页面,登录完成之后再跳转到个人中心,那我们使用通知回调不就行了吗?

在登录完成之后发出通知,在首页我们接受这个通知就调用去个人中心的方法不就行了吗?

使用通知的方式有很多,这里我们以LiveEventBus为例:

public class FunctionManager {
    private static FunctionManager functionManager;
    private static HashMap<String, Function> mFunctionMap;
    public FunctionManager() {
        mFunctionMap = new HashMap<>();
    }
    public static FunctionManager get() {
        if (functionManager == null) {
            functionManager = new FunctionManager();
        }
        return functionManager;
    }
    public void addLoginCallback(LifecycleOwner owner, ILoginCallback callback) {
        LiveEventBus.get("login", Boolean.class).observe(owner, aBoolean -> {
            if (aBoolean != null && aBoolean) {
                callback.callback();
            }
        });
    }
    public interface ILoginCallback {
        void callback();
    }
    public void finishLogin() {
        LiveEventBus.get("login").post(true);
    }
}

我们封装一个发送事件和一个接收事件,注意使用的时候添加回调的方法不要放在点击事件中。否则多次点击会重复调用的。

    override fun startObserve() {
        FunctionManager.get().addLoginCallback(this) {
            gotoProfilePage()
        }
    }
    override fun init() {
        mBtnCleanToken.click {
            SP().remove(Constants.KEY_TOKEN)
            toast("清除成功")
        }
        mBtnProfile.click {
            checkLogin()
        }
    }
    private fun checkLogin() {
        if (SP().getString(Constants.KEY_TOKEN, "").checkEmpty()) {
            gotoLoginPage()
        } else {
            gotoProfilePage()
        }
    }
    private fun gotoLoginPage() {
        gotoActivity&lt;LoginDemoActivity&gt;()
    }
    private fun gotoProfilePage() {
        gotoActivity&lt;ProfileDemoActivity&gt;()
    }

效果:

二、使用方法池

上面一种方法依赖于LiveData,我们都知道LiveData的值在一些特性情况下并不保险,当然我们可以使用FlowBus来缓解这一问题(只能在Kotlin项目中使用了),并且还存在使用不当,导致多次订阅,就会发生执行N此的逻辑。就需要我们再添加回调的方法中自己判断去重的逻辑。如果大家有兴趣也可以自行扩展,并不复杂

我们还可以使用另一种方便的方式,支持 Java 和 Kotlin ,我们使用方法池把需要执行的方法放入缓存中,当我们登录成功之后再把缓存中的方法拿出来执行,可以灵活放入多个方法。

定义方法对象

public abstract class IFunction {
    public String functionName;
    public IFunction(String functionName) {
        this.functionName = functionName;
    }
    protected abstract void function();
}

方法管理类

public class FunctionManager {
    private static FunctionManager functionManager;
    private static HashMap<String, IFunction> mFunctionMap;
    public FunctionManager() {
        mFunctionMap = new HashMap<>();
    }
    public static FunctionManager get() {
        if (functionManager == null) {
            functionManager = new FunctionManager();
        }
        return functionManager;
    }
    /**
     * 添加方法
     */
    public FunctionManager addFunction(IFunction function) {
        if (mFunctionMap != null) {
            mFunctionMap.put(function.functionName, function);
        }
        return this;
    }
    /**
     * 执行方法
     */
    public void invokeFunction(String key) {
        if (TextUtils.isEmpty(key)) {
            return;
        }
        if (mFunctionMap != null) {
            IFunction function = mFunctionMap.get(key);
            if (function != null) {
                function.function();
                //用完移除掉
                removeFunction(key);
            } else {
                try {
                    throw new RuntimeException("function not found");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 使用之后移除相关的缓存
     */
    public void removeFunction(String key) {
        if (mFunctionMap != null) {
            mFunctionMap.remove(key);
        }
    }
}

使用:

 override fun init() {
        mBtnCleanToken.click {
            SP().remove(Constants.KEY_TOKEN)
            toast("清除成功")
        }
        mBtnProfile.click {
            checkLogin()
        }
    }
    private fun checkLogin() {
        if (SP().getString(Constants.KEY_TOKEN, "").checkEmpty()) {
            FunctionManager.get().addFunction(object : IFunction("gotoProfilePage") {
                override fun function() {
                    gotoProfilePage()
                }
            })
            gotoLoginPage()
        } else {
            gotoProfilePage()
        }
    }
    private fun gotoLoginPage() {
        gotoActivity<LoginDemoActivity>()
    }
    private fun gotoProfilePage() {
        gotoActivity<ProfileDemoActivity>()
    }

我这里是为了兼容其他的场景使用,需要传入方法的key,如果大家只想用于拦截登录这一个场景,大家可以把Key的值固定化。

记得在LoginActivity中登录成功的时候回调处理

    fun doLogin() {
        showStateLoading()
        CommUtils.getHandler().postDelayed({
            showStateSuccess()
            SP().putString(Constants.KEY_TOKEN, "abc")
            finish()
            //方法池的方式
             FunctionManager.get().invokeFunction("gotoProfilePage")
            }, 500)
        }

效果和使用通知的效果一致

总结

不使用AOP我们一样能完成登录拦截的功能,思路不同但是实现的效果是相同的,使用原生的库或一些特性我们就无需再导入一个不好控制的库。

之前我们说过AOP框架的一些缺点,比如影响性能,编译慢,安装包体积大,Kotlin不友好,APG不友好等等,

那么这样使用方法池或者回调的方式有什么优缺点呢?

  • 优点:轻量,不影响性能,内存开销小,支持Kotlin、Java。
  • 缺点:相对使用没有AOP那么简便,判断是否登录的逻辑得自己写了。

当然了这种工具类管理的方式只是一种思路,实现的方法有很多,我这里只是举例两种用的比较多的方式回调与方法池,如果大家对此思路有优化的地方也可以评论区交流。

后期我会再出一些拦截登录的其他思路,比如基于Intent,基于线程池,基于协程等等,大家可以对比一下 AOP,方法池和其他一些实现思路,哪一种比较好。

以上就是Android基于方法池与回调实现登录拦截的场景的详细内容,更多关于Android登录拦截的资料请关注我们其它相关文章!

(0)

相关推荐

  • AndroidStudio 配置 AspectJ 环境实现AOP的方法

    昨天看了一段android配置aspectj实现AOP的直播视频,就试着自己配置了一下,可能是因为我自己的AndroidStudio环境的问题,碰到了不少的坑(其实还是因为对gradle理解的不多),但总归是配置好了,就分享一下. 试了两种方式,不过项目下的build.gradle,没什么变化,直接看一下代码吧: build.gradle(项目下) buildscript { ext { //android appcompat支持库版本 androidSupportVersion = '26.1

  • Android 采用AOP方式封装6.0权限管理的方法

    [一]背景 6.0运行时申请权限已经是一个老生常谈的内容了,最近项目TargetSDKVersion升到23以上,所以我们也需要做权限管理,我想到的需求是这样的: 1.支持单个权限.多个权限申请 2.运行时申请 3.无侵入式申请,无需关注权限申请的逻辑 4.除了Activity.Fragment之外,还需要支持Service中申请 5.对国产手机做兼容处理 第一.二点,Google都有对应的API: 第三点可以通过自定义注解+AOP切面方式来解决.为什么采用AOP方式呢?首先看AOP定义: 面向

  • Android中AOP(面向切向编程)的深入讲解

    一.闲谈AOP 大家都知道OOP,即ObjectOriented Programming,面向对象编程.而本文要介绍的是AOP.AOP是Aspect Oriented Programming的缩写,中译文为面向切向编程.OOP和AOP是什么关系呢? 首先: l OOP和AOP都是方法论.我记得在刚学习C++的时候,最难学的并不是C++的语法,而是C++所代表的那种看问题的方法,即OOP.同样,今天在AOP中,我发现其难度并不在利用AOP干活,而是从AOP的角度来看待问题,设计解决方法.这就是为什

  • Android面向切面基于AOP实现登录拦截的场景示例

    目录 前言 一.了解面向切面AOP 二.集成AOP框架 三.定义注解实现功能 总结 前言 场景如下:用户第一次下载App,点击进入首页列表,点击个人页面,需要校验登录,然后跳转到登录页面,注册/登录完成跳转到个人页面. 非常常见的场景,正常我们开发就只能判断是否已经登录,如果未登录就跳转到登录,然后登录完成之后怎么继续执行?如何封装?有哪些方式?其实很多人并不清楚. 这里做一个系列总结一下,看看公共有多少种方式实现,你们使用的是哪一种方案,或者说你们觉得哪一种方案最好用. 这一次分享的是全网最多

  • Android中AOP的应用实践之过滤重复点击

    前言 大家对AOP应该都不陌生, 就算没有用过也肯定听说过,切面编程一直是一个热点的话题,AOP即Aspect Oriented Programming的缩写,习惯称为切面编程;与OOP(面向对象编程)万物模块化的思想不同,AOP则是将涉及到众多模块的某一类问题进行统一管理,AOP的优点是将业务逻辑与系统化功能高度解耦,让我们在开发过程中可以只专注于业务逻辑,其他一些系统化功能(如路由.日志.权限控制.拦截器.埋点.事件防抖等)则由AOP统一处理; AspectJ简介 AOP是一种编程思想,或者

  • 浅谈Android面向切面编程(AOP)

    一.简述 1.AOP的概念 如果你用java做过后台开发,那么你一定知道AOP这个概念.如果不知道也无妨,套用百度百科的介绍,也能让你明白这玩意是干什么的: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合

  • Android基于方法池与回调实现登录拦截的场景

    目录 前言 一.使用通知与回调 二.使用方法池 总结 前言 前面的文章我们讲到APP登录拦截的功能实现,现在网上比较多的推荐使用AOP,我们使用下来还是太麻烦,兼容性问题很多,(坑太多,项目我已经改回来了,如果想体验AOP可以切换aop分支运行) 难道就想实现一个这么简单的功能,就非得使用AOP了吗?有没有简单一点的方式,方式其实太多了,个人感觉的话,完全没必要为了这么个小功能导入一个AOP库.今天我们看看使用方法池与通知回调的方式来处理登录拦截的逻辑. 一.使用通知与回调 其实本质逻辑就是想判

  • Android基于TextView属性android:ellipsize实现跑马灯效果的方法

    本文实例讲述了Android基于TextView属性android:ellipsize实现跑马灯效果的方法.分享给大家供大家参考,具体如下: Android系统中TextView实现跑马灯效果,必须具备以下几个条件: 1.android:ellipsize="marquee" 2.TextView必须单行显示,即内容必须超出TextView大小 3.TextView要获得焦点才能滚动 XML代码: android:ellipsize="marquee", andro

  • 基于Laravel5.4实现多字段登录功能方法示例

    前言 最近在一个项目中需要实现一个多字段登录功能,简单来说就是可以使用用户名.邮箱或手机号任意一种方式进行登录.所以本文就来给大家介绍了关于Laravel5.4多字段登录的相关内容,分享出来供大家参考学习,话不多说了,来一起看看详细的介绍吧. 以下内容基于laravel5.4 方法如下: 首先,通过artisan工具生成auth模块 php artisan make:auth 这时候App\Http\Controllers目录下会新增一个Auth目录,该目录下为注册登录相关的控制器,resour

  • Android基于Pull方式解析xml的方法详解

    本文实例讲述了Android基于Pull方式解析xml的方法.分享给大家供大家参考,具体如下: Pull解析和Sax解析很相似,都是轻量级的解析,在Android的内核中已经嵌入了Pull,所以我们不需要再添加第三方jar包来支持Pull. Pull解析和Sax解析不一样的地方有: (1)pull读取xml文件后触发相应的事件调用方法返回的是数字 (2)pull可以在程序中控制想解析到哪里就可以停止解析. 来看看实例: book.xml如下: <?xml version="1.0"

  • Android基于SoftReference缓存图片的方法

    本文实例讲述了Android基于SoftReference缓存图片的方法.分享给大家供大家参考,具体如下: Java中的SoftReference即对象的软引用.如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它:如果内存空间不足了,就会回收这些对象的内存.只要垃圾回收器没有回收它,该对象就可以被程序使用.软引用可用来实现内存敏感的高速缓存.使用软引用能防止内存泄露,增强程序的健壮性. SoftReference的特点是它的一个实例保存对一个Java对象的软引用,该软引用的存在不妨碍垃

  • Android基于Http协议实现文件上传功能的方法

    本文实例讲述了Android基于Http协议实现文件上传功能的方法.分享给大家供大家参考,具体如下: 注意一般使用Http协议上传的文件都比较小,一般是小于2M 这里示例是上传一个小的MP3文件 1.主Activity:MainActivity.java public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private EditText timel

  • Android基于OpenGL在GLSurfaceView上绘制三角形及使用投影和相机视图方法示例

    本文实例讲述了Android基于OpenGL在GLSurfaceView上绘制三角形及使用投影和相机视图方法.分享给大家供大家参考,具体如下: 定义三角形 OpenGL 允许我们使用三维坐标来定义物体.在绘制三角形前,我们需要定义它各个点的坐标.我们一般使用数组来存储各个顶点的坐标. OpenGL ES 默认 [0,0,0] (X,Y,Z) 在GLSurfaceView的中心,[1,1,0]在右上角,[-1,-1,0]在左下角. 绘制三角形 在绘制三角形之前,我们必须告诉OpenGL我们正在使用

  • Android基于Sensor感应器获取重力感应加速度的方法

    本文实例讲述了Android基于Sensor感应器获取重力感应加速度的方法.分享给大家供大家参考,具体如下: FETC项目指导老师提出了新的需求,想要在游戏地图中表现出用户用户当期移动的方向,再用GPS的话显然很不靠谱,所以想到了android强大的感应器... 很多移动设备都内置了感应器,android通过Sensor和SensorManager类抽象了这些感应器,通过这些类可以使用android设备的传感器 一 介绍Sensor类 SDK只有一句介绍"Class representing a

  • Android基于Intent实现Activity之间数据传递的方法

    本文实例讲述了Android基于Intent实现Activity之间数据传递的方法.分享给大家供大家参考,具体如下: MainActivity: package com.test.intentdemo; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.Menu; import andro

随机推荐