Android登录系统设计

一、前言

前段时间项目进入第一阶段的尾声,虽然登录方面的功能基本上已经完成开发,但是很乱,例如QQ登录等第三方登录有自己的缓存机制,本地的账号密码登录又是一种方式,邮箱手机号登录又是另一种方式,最终经过几个小时的逻辑推导,第一次在没有运行代码的情况下完成这个登录系统的开发,最终运行成功了,修改了一次没有初始化的情况,中间还出现了一些小插曲,最后完成这套系统的开发,目前app 已上线谷歌应用商店,欢迎大家来体验。

二、流程图

这个流程图包含了登录系统设计的全流程,也是当时模拟的时候一步步走的流程

在这里插入图片描述

简要的用文字梳理一下登录流程

  1. 首先进入程序,需要进行判断登录缓存是否存在且有效,有效直接跳转 MainActivity,否则跳转 LoginActivity
  2. 进入 LoginActivity 之后进行多种形式的缓存,这里的缓存是在各自的部分进行处理的,最后缓存成统一形式的Json数据,但有一点是必须保证的,在进入MainActivity时这些工作必须完成,因为后续即将使用到这些凭据
  3. 然后跳转 MainActivity 前可以携带一些数据,或者进行一些动画的展示
  4. 如果第一次登录的话进入MainActivity需要对全局application进行设置登录凭据,之后的登录在开始启动完成登录凭据的读取
  5. 注销登录之后务必进行缓存的清理,包括登录缓存,退出应用时对于其他临时保存的json数据进行清理,类似个人信息之类的
  6. 关于缓存是否有效,类似QQ等第三方登录有自己专门的检验机制,统一登录和邮箱登录这边我仅仅只做了时间上的验证,也可以考虑自定义设置验证机制,最后只要保证登录凭据的形式统一即可

这里关于启动界面采用Lottie view的形式展示,没有使用slash screen的设计,主要原因是想使得动画炫酷一点,然后也创建了BootActivity进行启动相关逻辑的处理,下图为启动界面图,这里由于引入动画,遇到一个坑(稍后会进行讲述)

在这里插入图片描述

三、主要设计部分分析

由于个人开发限制,下列登录方式的方式以QQ,邮箱,统一账号登录为例

1.登录缓存设计

统一登录行为是这个系统设计的核心,所以这部分的设计以简单和信息最小化为原则进行设计,下面这四个字段足够用了,也可以自行扩展

//首先是唯一id字段,这个字段可以是第三方的openId也可以是其他的数据,只要保证数据唯一即可
//过期时间这个是可以设置的,登录的途径,与程序启动和进行统一账号的生成有关
data class LoginInfo(var id:String = "", var expireTime:Long = 0, 
                     var loginWay:String = "",var loginToken:String = "")

设计这样一个统一的缓存bean,然后利用 MMKV 进行键值存放相关的 json 数据,这里简单封装了 Gson使用Kotlin的扩展函数完成json和对象之间的转化,具体可以参考这篇文章Json和对象之间转换的封装(Gson)

//String.toMyObject<>()为转化成对象的形式
//Any.toMyJson()为转化成json数据的封装

val kv = MMKV.defaultMMKV()
val loginInfo = LoginInfo(...)
kv.encode("login_info",loginInfo.toMyJson())

这个部分在进行各种途径登录成功之后完成缓存操作

2.数据通讯设计

login 缓存

这个相当重要,设计缓存很多时候就是方便各个activity进行通信的,之前采用的是activity传值的方式进行的,每次传递都要编写一次代码,而且还容易出错,考虑到 login 这部分缓存具有很强的复用性,所以这部分需要放在全局的application中,然后需要的时候直接调用application即可。所以login 这部分的缓存是长期存放的数据,在登录成功之后进行设置application相关的缓存,同时也要考虑第一次登录或者注销登录之后的操作

companion object{
    @SuppressLint("StaticFieldLeak")
	...
    lateinit var login_info:LoginInfo
    ...
}

override fun onCreate() {
    super.onCreate()
    ...
    login_info = if (MMKV.defaultMMKV().containsKey("login_info")){
        //包含即可认为不为空直接读取
        login_info = MMKV.defaultMMKV().decodeString("login_info").toMyObject<LoginInfo>()[0]
    }else{
        //否则初始化对象,这里如果未初始化会报错
        login_info = LoginInfo()
    }
    ...
}

login 部分的衍生缓存

这部分需要在MainActivity里面进行操作,确保有login部分的缓存之后进行的操作,这部分可以根据自己的需求进行,我的做法是一旦失败回到登录界面,当然无网络或者弱网也会触发这个,这个就属于自己的个性化选择了,目前我自己的这个项目没有网络几乎不能完成任何操作,所以选择了这个做法。衍生缓存也可以根据自己的需要进行持久化缓存或者只存在在内存中,我这里的做法同login部分的,只是每次退出应用后都销毁这部分缓存(这部分主要是为了信息方面的安全考虑的),login部分不销毁

例如这个QQ的获取个人信息,需要qqToken才能获取,即之前登录凭据中的accessToken

private fun getQQInfo(){
    val qqToken = mTencent.qqToken
    val info = UserInfo(Application.context,qqToken)
    info.getUserInfo(object : DefaultUiListener(mTencent){
        override  fun onComplete(response: Any?){
            kv.encode("qq_info",response.toString())
        }
    })
}

当退出MainActivity时,移除这部分的缓存即可,如果有一些不可变的数据,可以考虑持久化,这里使用kv当时是为了方便,可以全局通信,使用全局的application也是可以的,效果一样,如果想要后续进行一些其他的持久化可以考虑MMKV

kv.remove("qq_info")

3.数据异常处理

关于 BootActivity的一些坑

这里主要是考虑这样一个场景,当用户在等待启动动画的时候,由于意外切换到了后台,然后再次进入,由于动画的跳转是有条件的,即跳转逻辑还没处理完毕,导致退出之后,动画一直在循环(跳转逻辑这部分被跳过了),这里的解决方案是调整逻辑处理的位置,放在onStart里面进行处理,如果onPause启动了,并且onStart部分的登录验证有效,就直接跳转MainActivity,省略动画(其实还可以记录时间给予最佳体验),如果无效则重新启动onStart中的逻辑,用到了一些简单的逻辑判断

private var loginValid = false
private var onPause = false
... 
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    //这里onCreate建议完成一些轻量级的任务,否则很有再次出现这种情况
}
override fun onStart() {
    super.onStart()
    if (!onPause){
        //跳转逻辑
        //跳转逻辑中的登录有效则
        //loginValid = true
        //否则不处理
    }else{
        //这里的startActivity参考郭神的第一行代码里面的重载函数
        startActivity<MainActivity>(Application.context){}
    }
}

override fun onPause() {
    super.onPause()
    if (loginValid){
        onPause = true
    }
}

login 缓存部分数据被破坏

这部分的处理比较简单,可能由于 MMKV 缓存出错(听说这个概率极低,但还是以防万一),一旦比如进行某种请求时发现数据查找不到记录,此时可以销毁key然后跳转到登录界面重新登录

//这里之所以销毁全部key是因为,如果login_info这部分最重要的key出问题了,必须退出登录
kv.clearAll()
startActivity<LoginActivity>(context){}
finish()

如果是获取其他依赖login_info的数据,多次出错,可能是服务端的问题,也有可能是MMKV出问题了,此时重新登录是比较好的选择

val retry = 0
//网络请求
...
if(retry > 5){
    kv.clearAll()
    startActivity<LoginActivity>(context){}
    finish()
}

这部分最重要的就是login_info这个key了,如果这个数据损坏只能重新登录

4.涉及的activity以及它们各自的任务

  • BootActivity 负责下一次进入的跳转处理和首次进入的初始化,同时可以放一些动画,例如Lottie View,具体见官网的使用

<com.airbnb.lottie.LottieAnimationView

          android:id="@+id/animation_view"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          app:lottie_autoPlay="true"
          app:lottie_fileName="boot.json"
          app:lottie_loop="true" />
  • LoginActivity 负责各种登录途径的入口处理,并不涉及具体登录逻辑

class LoginActivity :BaseActivity<ActivityLoginBinding>(ActivityLoginBinding::inflate) {

  ...
  override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      ...
      viewBinding.qqLogin.setOnClickListener {
          ...
          //qqlogin部分处理
         	...
      }
      viewBinding.mailLogin.setOnClickListener {
          ...
              startActivity<MyLoginActivity>(FundTestApplication.context){
                  putExtra("way","mailLogin")
              }
         ...
      }
      viewBinding.passwordLogin.setOnClickListener {
         ...
              startActivity<MyLoginActivity>(FundTestApplication.context){
                  putExtra("way","passwordLogin")
              }
         ...
      }
  }

}

  • MyLoginActivity负责具体逻辑的处理
  • QQ 这里使用 UIListener进行处理,同时sdk自带的activity完成登录具体逻辑的处理
  • 邮箱和统一账号登录由此activity进行处理,需要完成两项任务
- 本地数据的合法性检验(可以减少服务端的负担)
- 发送本地的账号密码/邮箱验证码进行服务端那边的验证

四、三种登录方式具体设计

1.第三方登录设计

这里以 QQ 举例,有兴趣的朋友可以参考上次写的QQ登录集成

QQ等第三方平台一般登录之后会生成自己的凭据,提取有用的信息作为缓存的登录凭据,比如唯一的 openId,access Token ,过期时间,其他的信息如果有需要的自行进行提取,这三个是最基本的,如果只是登录的话,openId保证唯一性,accessToken保证数据的准确性,QQ平台有相应的验证登录是否有效的机制,不需要我们进行验证处理。

设置第三方登录凭据

这部分在登录成功之后即可开始

val qqLogin = loginData.toMyObject<QQLogin>()

//首先设置QQ登录需要的凭据
mTencent.setAccessToken(qqLogin.access_token, qqLogin.expires_in.toString())
mTencent.openId = qqLogin.openid

设置缓存的登录凭据

val loginInfo = LoginInfo(qqLogin.openid,qqLogin.expires_time,"qq",qqLogin.access_token)
kv.encode("login_info",loginInfo.toMyJson())

当首次进行登录时,需要设置到全局的application里

Application.login_info = loginInfo

2.验证登录

首先验证登录的安全系数其实已经挺高了,目前主流的做法还有添加是否为机器人的检验,这部分暂时还没做,只做了验证码的验证

  • 常见的几种形式

手机号、邮箱等,目前个人开发者只能使用邮箱进行发送验证码,手机号短信需要企业用户

  • 验证码的生成

这里仅仅采用随机数的方法进行生成6位数字,不过这里就是服务端那边的工作了

  • 统一登录的凭据中其他字段的生成

val loginInfo = LoginInfo(mail,expires_time,"mail","")

//id字段使用登录邮箱作为唯一id

//过期时间这里采用缓存时间+当前的时间生成过期时间戳,这里缓存一个月

//判断时只需要当前时间与过期时间进行比较即可

val expireTime = 30864001000L + System.currentTimeMillis()

//登录途径这里即mail

//accessToken这里如果没有设计的话置空即可

3.统一账号登录

这个需要对每个第三方登录或者验证登录进来的账号进行处理,这里参考 CSDN 的id命名,途径+8位数字组成唯一id,这个id可以进行账号密码登录,所以这里没有设计账号注册系统了,主要考虑到其实大部分注册也需要邮箱手机号验证,目前也有好多平台没有自己的账号注册系统,不过自己可以给自己创建一些测试的账号便于登录

  • 统一账号设计

这里采用登录途径+8位纯数字构成统一id,重复了进行重新生成

fun uid(platform:String):String{

  return "${platform}_${(Random().nextInt(99999999 - 10000000 + 1)+10000000)}"

}

//例如qq_36725737

//即代表由qq平台登录的

  • 登录凭据设置

这里id即可替换成统一账号即可,都是唯一的无需担心重复,过期时间参考验证登录,途径这里设置成password即可,accessToken这里也同验证登录,同时如果时密码登录的话就不需要注册了

  • 然后这里提供忘记密码的选项,直接引导用户进行邮箱登录的提示,然后进入主界面里面进行设置密码,毕竟重置密码还是需要验证码的

五、总结

这次的登录流程的设计受益匪浅,统一的登录行为是设计中最核心的部分,可以进行扩展,同时便于进行管理,不过仍然有不足的地方,例如异地登录方面的考虑和设计,防机器人等的设计

六、应用界面

目前利用此登录系统开发的app已经上线谷歌应用商店,算是上架的第一个应用,搜索VFund即可,欢迎前来体验

部分界面展示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

原文地址:https://cloud.tencent.com/developer/article/2059530

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


所以很多人都会选择将这些生活琐事来交给智能化产品,在众多产品中,扫拖机器人所给我们带来的便利性最强,扫地、拖地全都一气呵成,不需要人为过多干预,不过目前大多数扫拖机器人对于双手解放得不彻底。而石头作为
“昨天的经历都将成为明天的力量。” 将绝大部分精力都奉献给璃月港的刻晴,可以说是《原神》中的高人气角色了,虽然是常驻角色,并且对于普通玩家来说……刻师傅别刮了……不过作为开服就存在的角色,还有独特的剑法
最近,全球知名的通信产业盛会MWC 2024(2024世界移动通信大会)正式召开,其中,联发科以“连接AI宇宙”(Connecting the AI-verse)为主题,为大众展示出一系列在AI和移动通信技术等领域的最新突破,吸引了大量行业
今年上半年有很多值得关注的机型,其中华为最新的影像旗舰华为P70 Art也自然受到了业界不少的关注目光,目前关于这款机型的轮廓图已经在网上曝光。
目前,2024世界移动通信大会(MWC)正在西班牙巴塞罗那举行,值得一提的是,此次大会参展中国厂商非常多,包括华为、中兴、小米、荣耀等等多家厂商均在其列。
就在去年,真我推出了11 Pro+,用一个2亿像素传感器和zoom变焦功能,开启了中端手机影像的长焦大战,而后友商才姗姗来迟的跟进了2亿像素传感器。
【手机之家新闻】一年一度的MWC已经于当地时间2月26日在巴塞罗那正式开展,在本次MWC2024上全球各大厂商齐聚一堂,展出自家最新的技术与产品,其中中兴就参展本次MWC2024,并且展出了诸多面向企业端的产品,而旗下的
近日,联发科在MWC 2024(2024 世界移动通信大会)上展出了一系列令人瞩目的AI和移动通信技术突破,以“连接AI宇宙”(Connecting the AI-verse)的展厅吸引了无数业界精英和媒体的目光。特别是其现场的生成式AI技术
虽然目前国内已经有不少厂商入局折叠屏产品,但是努比亚却迟迟没有入局。不过在近日举办的MWC 2024展会上,努比亚发布了自家首款折叠屏手机——努比亚Flip,预计国内很快也会上市。
MWC 2024正在西班牙巴塞罗那举办,和往年一样,荣耀这次依旧携众多新产品、新技术参会。荣耀Magic6 Pro、荣耀Magic V2 RSR保时捷设计的机型在海外正式发布,并且还展示了魔法大模型、任意门等诸多新技术。
MWC 2024正在西班牙巴塞罗那如火如荼地举行,其中小米也参加了今年的大会,在会上发布了在国内大受欢迎的小尺寸旗舰——小米14。值得一提的是,高通公司CEO安蒙甚至亲临发布会现场为这款机型助阵。
《原神》是一直以来在机圈深受欢迎的游戏,在充满幻想的提瓦特大陆上,你可以邂逅不少性格迥异、能力独特的伙伴。而一加Ace系列一直就拥有非常强烈的电竞属性,也是畅玩《原神》的热门机型,而在本月,一加Ace 3将推
有不少网友发现,今年新机的发布时间相对于往年大幅提前,很多厂商在春节之前密集发布了自己最新的中高端机型,给人一种年后没什么新机可发了的感觉。不过魅族全新的大杯机型——魅族21 PRO非常值得期待,魅族科技也
2022年7月,小米12S Ultra正式发布,这款产品率先将1英寸大底主摄引入到移动影像领域,同时凭借鲜明的徕卡影调给人留下深刻的印象,同时这款产品也被视为了影像旗舰地位的机型。如果从那时算起,到现在差不多已经快过
随着智能手机的日益普及和智能化进程的加速,智能穿戴设备成为了人们关注的焦点。各大智能手机厂商纷纷进军智能穿戴市场,试图在这一新兴领域抢占先机。
早在去年秋天,HyperOS操作系统发布的时候,小米便勾勒出了“人车家全生态”的美好蓝图,而在这其中,小米的多终端统一战略是核心,目前已经有不少小米产品预装或者接受到了HyperOS操作系统的推送,在过去几个月的时
今年雷军将把更多的精力放在小米汽车上,所以接下来的手机业务将由刚刚兼任小米品牌总经理卢伟冰接管。同时雷军也在微博上表示小米2024年开年旗舰——小米14 Ultra即将在近期发布,并且将有卢伟冰进行讲解。另外,卢
新的一年有龙则灵,有愿必达。自1月19日起,荣耀加码“新年荣耀,一起成龙”年货节,在全国荣耀线下门店上线了“新年许愿处”、“龙运当头”等趣味活动,吸引大批消费者到店打卡许愿,戴龙头迎好运。与此同时,为了回
小米在官网微博中已经透露了关于小米14 Ultra信息,所以新机上市应该不会太晚。根据德国莱茵的官方消息,目前小米14 Ultra(型号为24030PN60G)获得了莱茵无频闪认证,表明这款手机可以有效减轻屏幕给用户带来的视觉疲
2月22日,上海广播电视台与华为举办鸿蒙合作签约仪式,宣布其官方客户端看看新闻APP将基于HarmonyOS NEXT鸿蒙星河版启动鸿蒙原生应用开发,为用户提供更加极致的新闻资讯服务体验。此次合作标志着上海广播电视台成为全国