从0到1实现一个Android路由——URL解析器
Posted xingfeng_coder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从0到1实现一个Android路由——URL解析器相关的知识,希望对你有一定的参考价值。
从0到1实现一个android路由系列文章
- 从0到1实现一个Android路由(1)——初探路由
- 从0到1实现一个Android路由(2)——URL解析器
- 从0到1实现一个Android路由(3)——APT收集路由
- 从0到1实现一个Android路由(4)——多模块的APT收集路由
- 从0到1实现一个Android路由(5)——对Kotlin模块的支持
- 从0到1实现一个Android路由(6)——拦截请求再跳转
在从0到1实现一个路由(1)——初探路由中,介绍了一个五脏俱全的路由例子,路由是通过URL到达页面,那么URL解析器是个很重要的步骤,负责解析、跳转、拦截、传参等等。
所谓URL解析器,可以看成是URL和Intent的映射,因为Android启动页面只能通过Intent来跳转,不论是显试调用还是隐式调用,归根结底是一个Intent。
URL解析器改造
在上个例子的基础上,进行改造,将URL解析器作为单独模块抽出。
结构如下:
fun urlProcess(context: Context, url: String): Intent?
return null
URL传参
通过URL到达页面,URL是可以携带参数的,比如GET请求中的url就是含有参数的,我们可以利用该特性对第一篇中的例子加以改造。
URL格式定义
URL形式为scheme://host:port/path?query
query的形式为key1=value1&key2=value2。
携带参数的路由跳转
定义好格式后,新的路由跳转修改为:
//本app支持的scheme
else if (url.startsWith("easyrouter"))
with(URI(url))
for ((key, value) in routeMap)
if (key.equals(path))
return Intent(context, value).apply
if (!TextUtils.isEmpty(query))
query.split("&").forEach
it.split("=").apply
putExtra(get(0), get(1))
主要改变是url只要以路由表中的key开头,就能跳转到该Activity,同时也允许不传参的跳转,带有参数的则解析然后放到Intent中进行跳转。
这样的方式需要注意页面对默认值的一些处理,因为有时有些key可能是不提供的。
调用方
val paramsActivityUrl = "/paramsActivity"
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnWithParams.setOnClickListener
goToPages(this, paramsActivityUrl + "?firstname=hello&secondname="world")
btnWithoutParams.setOnClickListener
goToPages(this, paramsActivityUrl)
定义好了key之后,再从ParamsActivity中取出就可以了。
URL拦截
经常会遇到跳转到一个页面之前需要首先进行登录操作,那么如果在没有登录的状态下,需要先跳转到登录页面。这里就可以通过URL拦截来实现登录拦截。
拦截需要考虑的点是:如何在拦截后继续跳转到目的页面。比如登录拦截,登录页面好启动,登录成功后,通常逻辑是进入首页,这时如何跳转到目的页面呢?关于这一点,因为原有的页面跳转逻辑都是有的,比如登录成功后就跳转到首页,而现在需要改变跳转逻辑,实现的话侵入会比较严重,需要用到Hook。在寻求解决方案中,先看个简单点的拦截。
举个例子:在跳转SecondActivity之前弹出一个对话框来决定是否继续跳转,新的处理逻辑如下:
un goToPages(context: Context, url: String)
if (url.contains("/secondActivity"))
AlertInterceptor().interceptor(context, URI(url),
object : OnSuccessListener
override fun onSuccess(context: Context, uri: URI)
urlProcess(context, url)?.apply
context.startActivity(this)
,
object : OnErrorListener
override fun onError()
Toast.makeText(context, "用户取消了跳转", Toast.LENGTH_SHORT).show()
)
else
urlProcess(context, url)?.apply
context.startActivity(this)
在处理url之前,首先交给AlerInterceptor处理一把,通过两个接口将是否继续跳转通知出来。 Interceptor的结构如下:
nterface OnErrorListener
fun onError()
interface OnSuccessListener
fun onSuccess(context: Context, uri: URI)
interface Interceptor
fun interceptor(
context: Context,
uri: URI,
onSuccessListener: OnSuccessListener? = null,
onErrorListener: OnErrorListener? = null
)
class AlertInterceptor : Interceptor
override fun interceptor(
context: Context,
uri: URI,
onSuccessListener: OnSuccessListener?,
onErrorListener: OnErrorListener?
)
AlertDialog.Builder(context).apply
setTitle("拦截提示")
setMessage("是否跳转SecondActivity")
setPositiveButton(
"确定"
) dialog, _ ->
onSuccessListener?.onSuccess(context, uri)
dialog.dismiss()
setNegativeButton(
"取消"
) dialog, _ ->
onErrorListener?.onError()
dialog.dismiss()
.create().show()
降级策略
url匹配,如果匹配不到Activity那应该怎么办?是否可以跳转到一个默认页面,比如说首页?
这里可以通过降级策略来实现。
可以通过接口暴露给上层,交由开发者自己实现,这里就先简单写死,概念最重要。
在urlProcess()方法最后加上一个默认的Intent,如下:
fun urlProcess(context: Context, url: String): Intent?
...
return Intent(context, DegradeActivity::class.java).apply
putExtra("error_msg", "没有找到目标页面")
总结
本文主要在第一个的例子上增加了URL解析器,增加了URL拦截、传参、降级的功能。关于代码,可以参考url_processor分支。
参考阅读
关注我的技术公众号,不定期会有技术文章推送,不敢说优质,但至少是我自己的学习心得。微信扫一扫下方二维码即可关注:
以上是关于从0到1实现一个Android路由——URL解析器的主要内容,如果未能解决你的问题,请参考以下文章
从0到1实现一个Android路由——对Kotlin模块的支持