前言
关于App实现登录的拦截再执行逻辑,我已经出了几篇方案了,有些同学可能会问,你整的一些花里胡哨的有啥用,原生的Intent就能实现这些功能,我都是这么用的。
其实也没错,其实我之前也是这么使用Intent用的,应该算是比较基本的用法。下面一起看看基于Intent怎么实现登录拦截,又有哪些实现的方式?好不好用呢?
一、ResultApi
最基本的用法就是 startActivityForResult onActivityResult ,当然这一种方案已经Out了,谷歌也推荐我们使用Result Api,关于这一点后期会单独讲,这里还是以 onActivityResult 为例子。
//Intent的方式
mBtnProfile2.click {
if (!LoginManager.isLogin()) {
gotoLoginPage()
} else {
gotoNextPage()
}
}
fun gotoLoginPage() {
val intent = Intent(mActivity, LoginDemoActivity::class.java)
startActivityForResult(intent, 1010)
}
fun gotoNextPage() {
val intent = Intent(mActivity, ProfileDemoActivity::class.java)
startActivity(intent)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
YYLogUtils.w("基于Result实现")
if (requestCode == 1010 && resultCode == -1) {
gotoNextPage()
}
}
启动到登录页面,然后返回到当前页面,接收到返回事件之后对结果做处理,继续执行。
效果:
确实,刚入坑安卓的同学都会写的代码就能实现的逻辑,我为什么要整那么多花活,是因为方便
和 简洁
。可能有些同学不理解,这里我简单说一下。
比如一个页面中有多个地方需要判断登录再执行,需要写这些代码就太多了,还需要维护一个庞大的 onActivityResult 。
又比如如果我们是单Activity+Fragment的架构,我们需要跳转Fragment的,那你跳转Activity的Intent又不符合。又如何使用Intent跳转到Fragment呢?
再比如如果我们的逻辑不限于跳转页面,比如Dialog弹窗也需要校验登录,怎么办?比如弹出PopupWindow, 比如吐司,气泡,下拉选,等等逻辑,Intent能不能实现呢?代码会不会越来越多呢。越来越复杂呢?
所以才会整出那么多花活,就是为了简洁,方便,支持 runnable 或 高阶函数类型 或 function 等等,就是为了灵活。具体的可以看看之前的几种方案。
二、Intent的解析
说了那么多,Intent能不能实现上述说的功能呢?是可以的,只是相对麻烦,代码很多,但是是可以实现的。
如果是传统的Intent方法,那么我们通常是定义一些类型,在 onActivityResult,再根据判断不同的类型调用不同的方法。
companion object {
val type_profile_page = 0x21
val type_dialog = 0x22
val type_picker = 0x23
}
mBtnProfile2.click {
if (!LoginManager.isLogin()) {
val intent = Intent(mActivity, LoginDemoActivity::class.java)
intent.putExtra("type", type_profile_page)
startActivityForResult(intent, 1010)
} else {
gotoNextPage()
}
}
mBtnProfile3.click {
if (!LoginManager.isLogin()) {
val intent = Intent(mActivity, LoginDemoActivity::class.java)
intent.putExtra("type", type_dialog)
startActivityForResult(intent, 1010)
} else {
gotoNextPage()
}
}
mBtnProfile4.click {
if (!LoginManager.isLogin()) {
val intent = Intent(mActivity, LoginDemoActivity::class.java)
intent.putExtra("type", type_picker)
startActivityForResult(intent, 1010)
} else {
gotoNextPage()
}
}
//返回的回调中再判断不同类型,调用不同的方法
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
YYLogUtils.w("基于Result实现")
if (requestCode == 1010 && resultCode == -1) {
when (data?.getIntExtra("type", 0) ?: 0) {
type_profile_page -> {
//跳转到个人中心页面
toast("跳转到个人中心页面")
}
type_dialog -> {
//展示弹窗
toast("展示弹窗")
}
type_picker -> {
//展示PickerView
toast("展示PickerView")
}
}
}
}
Login的页面就需要拿到携带过来的type,在返回回去
private var mTargetType = 0
override fun init() {
mTargetType = intent.getIntExtra("type", 0)
}
fun doLogin() {
showStateLoading()
CommUtils.getHandler().postDelayed({
showStateSuccess()
SP().putString(Constants.KEY_TOKEN, "abc")
setResult(-1, Intent().apply { putExtra("type", mTargetType) }) //设置Result
finish()
}, 500)
}
使用隐式Intent的方案
另一种方案我们也可以通过inent的隐式跳转,封装一个Intent,然后让Login帮我们执行这个Intent,通过newIntent的形式拿到Intent携带的数据。即可完成逻辑,例如我们首页切换底部的BottomTabBar
inner class ClickProxy {
fun switchPage0() {
switchFragment(0)
}
fun switchPage1() {
if (!LoginManager.isLogin()) {
val intent = Intent(mActivity, Demo3Activity::class.java)
intent.addCategory(switch_tab1)
gotoLoginPage(intent)
} else {
switchFragment(1)
}
}
fun switchPage2() {
if (!LoginManager.isLogin()) {
val intent = Intent(mActivity, Demo3Activity::class.java)
intent.addCategory(switch_tab2)
gotoLoginPage(intent)
} else {
switchFragment(2)
}
}
fun switchPage3() {
if (!LoginManager.isLogin()) {
val intent = Intent(mActivity, Demo3Activity::class.java)
intent.addCategory(switch_tab3)
gotoLoginPage(intent)
} else {
switchFragment(3)
}
}
}
fun gotoLoginPage(targetIntent: Intent) {
val intent = Intent(mActivity, LoginDemoActivity::class.java)
intent.putExtra("targetIntent", targetIntent)
startActivity(intent)
}
//通过这样的方式可以拿到携带的数据
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
YYLogUtils.w("收到newintent:" + intent.toString())
val categories = intent.categories
when (categories.take(1)[0]) {
switch_tab1 -> {
switchFragment(1)
}
switch_tab2 -> {
switchFragment(2)
}
switch_tab3 -> {
switchFragment(3)
}
}
}
运行效果:
总结
总的来说,不是很推荐Intent的方式。
使用Intent的方式,每一个跳转的地方都需要写判断逻辑和代码,并且在一些类似Dialog等页面不能使用 onActivityResult 的地方,还需要 Activity/Fragment 中转消息,使用有局限性。
使用隐式Intent在 Fragment/Dialog 等一些非Activity的场景使用不方便,需要Activity再次中转消息,比较麻烦。
但是可以看到Intent确实是可以实现登录拦截的逻辑的,就是有点麻烦而已,为什么不一开始就写这一种方式,是为了提现其他方式的封装行与便捷性。
以前我也不知道其他方式,我自己也是使用Intent的方式的,但是现在我有的选,其他的更加便捷的方式不是更方便吗?何必为难自己,维护一个Intent的多个类型Type好麻烦哦。
当然我自己闭门造车,可能有更优的办法,如果对Intent的方式有什么更好的方法,大家可以评论区交流。
后期我会再出一些拦截登录的其他思路,大家可以和Intent或之前的方式做一下对比,的哪一种比较好,更加的方便。
作者:newki
链接:https://juejin.cn/post/7134126903073439775
来源:稀土掘金