玩转编程涛锅锅的Android资料

[技术探究] 使用Fragment完全代替Activity的可行

2018-01-27  本文已影响5832人  欧阳锋

Activity是一个非常令人讨厌的设计!Activity的创建并不能由开发者自己控制,它是通过多进程远程调用并最终通过放射的方式创建的。在此期间,AMS需要做大量的工作,以至于Activity的启动过程极其缓慢。另外,在宽屏设备上,如果需要多屏互动时,Activity的局限性也就表现了出来。为此Android团队在Android 3.0的时候引入了Fragment。Fragment的出现解决了上面两个问题,但也带来了一些问题:1)Fragment生命周期设计复杂,到现在为止我都不能完全记下来!2)到底什么时候应该用Fragment,什么时候应该用Activity呢?3)如果我要直接跳转至Fragment怎么办?众所周知,iOS在所有版本的系统中设计都仅有UIViewController一个控制器,同样可以支撑所有业务需求。那么,Android端是否可以通过Fragment完全替代Activity呢?

在公司的最新应用中,我已经实现了使用全Fragment代替Activity,并且可以直接通过上下文路由到某个Fragment。因此,我的新开源框架 ViewController 已经准备好了,希望更多的同学可以享受到这个福利。但我知道,距离【完全取代】还有一定的距离。

在开源框架中,我不再称其为Fragment,改名为ViewController。因此,以下全部称为ViewController。

针对这样的设计,我们至少还需要解决以下几个问题:
1)如何设计入口ViewController
2)如何实现对软键盘的控制,类似Activity可以在清单文件中指定软键盘显示模式
3)如何实现对Window的控制
4)如何实现scheme跳转(etc: snake://main?id=163)
5)如何实现在多进程中开启ViewController

针对问题1),我们可以使用编译期注解标记,动态生成代码注入到Activity中,在启动Activity的时候默认选择该Fragment替换主布局,就实现了入口ViewController的设计。

这里可能有人会问,如果要finish当前ViewController,不希望其回退呢?这里我们可以使用replace的方式解决。

针对问题2),这是一个相当棘手的问题,Android系统没有提供相关API来获取软键盘的显示状态,软键盘的高度等信息。目前,Github上面已经出现了一些获取软键盘显示状态的方法,其实都不是完美的解决方案。因此,这个问题有待商榷。如果有完美解决方案,将发布在我的Android难点开源库中。

针对问题3),这又是一个麻烦的问题,Window是和Activity绑定的,如果要实现这个绑定关系,必须先解除其与Activity的绑定。目前,脑海中比较理想的解决方案是尝试将decorView设置到入口ViewController中,具体是否可行,有待尝试。

针对问题4),scheme的跳转是一个很有用的设计,其主要应用在多个应用直接互相通信。比如,你常用的微信登录、微信支付,就是一个scheme跳转的例子。因此,这个功能在ViewController中也必不可少。由于系统的这种设计限制,这个部分的实现依然需要依赖Activity。可是,问题来了。由于全部都是ViewController,scheme的设置又必须在清单文件中,如何动态写入清单文件呢?这里考虑Hook的方式实现Activity的拦截创建,绕过系统对清单文件的检查,但这里的scheme检测如何通过呢?这是本次代码设计的一大最难点之一,具体设计有待尝试。

针对问题5),熟悉多进程编程的同学都知道,四大组件都可以在清单文件中添加android:process标记指定多进程名称,系统就会为这个组件单独再启动一个进程。这的确是一个非常方便的设计。可是,系统并没有为ViewController提供这样的设计。这里考虑参考Activity的设计使其开在单独的进程中。大部分同学都是单进程编程,仅仅是第三方的一些库可能会使用多进程,比如JPush等。因此,这个功能优先级较低,前期可以通过嵌入Activity实现多进程。

ViewController能为你做什么?

1)解决你的选择恐惧症,始终使用ViewController作为控制器
2)解决Activity启动缓慢问题,ViewController本质就是Fragment,Fragment更轻量,启动速度更快
3)控制更灵活,既可以选择系统创建,也可以选择手动创建ViewController实例
4)忘记清单文件,不再需要因为新增页面频繁写入清单文件的尴尬
5)简化生命周期,避免Fragment类似冗长的生命周期设计
...

ViewController会提供怎样的API?

ViewController力求提供尽可能简洁的API,举个例子,看下面:

// 跳转至指定ViewController(系统创建)
public void push(Class<? extends ViewController> viewController) {}
// 跳转至指定ViewController(手动创建)
public void push(ViewController viewController) {}
public void pop() {}

关于ViewController,你是怎么想的呢?你是否也希望拥有这样一个更纯粹的控制器?如果你赞同我的设计,关于文中的五个问题,你有什么设计思路可以分享一下呢?请在屏幕下方留言告诉我!

如果你支持我,请来这里:https://github.com/yuanhoujun/ViewController,点击右侧star支持我,我会在近期开源该项目。

更多内容,请关注我的微信公众号:欧阳锋工作室,近期会同步更新技术类文章。


公众号 | 欧阳锋工作室
上一篇 下一篇

猜你喜欢

热点阅读