本文首发于简书——何时夕,搬运转载请注明出处,否则将追究版权责任。交流qq群:859640274
有人说我标题党,也怪我开始决定写的时候没有注意标题,也没想到会有这么多阅读量,的确会生出一些是非出来。那么从现在开始标题改为 从零开始仿写一个抖音App 系列。希望技术讨论能够多一点,没看文章就喷的人能够少一点。我会坚持写下去,好好提升自己的能力。
连载文章
本项目的 github 地址:MyTikTok
一、写在前面
这个坑可能会持续很久,之前开过好几个坑,但是都不长久。原因是计划赶不上变化。每过一段时间我都会感觉有更重要的事情要去做,所以之前开的坑就被我抛弃了。但是这一次不同,具体的不同点我会在下面一一列举出来。
- 1.关于目的:笔者目前在抖音的竞品里面做android端的视频拍摄和编辑这块。大公司大家也知道,各个业务都是分层的,所以我们平时的业务都是在音视频架构组封装的sdk之上进行的。所以一旦时间长久了自身的竞争力就会减弱,毕竟没有掌握“核心科技”。好在sdk的源码是内部开放的,所以我可以读读源码去了解“核心科技”。正好读了源码之后可以练练手,自己去实现一遍,这就是本项目诞生的初衷。
- 2.关于代码:首先由于保密协议,我们公司的源码是绝对不能开源出去的,因此本项目的全部代码都将会是我自己根据读源码获取到的思想最后实现的。所以本项目最终在性能、兼容性、代码可读性都是不如原本的代码的,所以如果有读者要集成入商业项目的话请慎重。
- 3.关于项目:本项目预计会持续1-2年的时间,除非我中途离职了,否则一定会坚持更新。目前的预期是每两周更新一篇博客,与此同时更新一版feature。此外本项目虽然说是写一个抖音App,但其实最终项目中的实现只会是抖音App中各种特效的实现集合,至于和服务器交互还有界面的交互方面我并不会花费很长时间去写。当然除了抖音App中的特效,我有一个爱好是深度学习,所以我将会制作一些基于深度学习的特效集成到项目中,所以有这方面爱好的同学也可以和我多多交流。
- 4.飨读者:本项目虽然是我自己的练手项目,但是也有部分目的是希望让一部分不甘于现状想深入学习android的同学和我共同进步。所以大家有项目上面的问题和github上的issue都欢迎和我交流。
二、项目概述
这一节我主要是想对未来项目做一个概述吧,说一下项目的技术栈,这样也好让大家对项目有一个概念。
- 1.MVP:这是项目的架构方式,熟悉架构的同学应该知道现在android中有三种架构方式:MVC、MVP、MVVM。为何选择MVP想必大家也都清楚,首先MVC非常老旧也有一堆缺点所以第一个排除。然后是MVVM虽然这种架构已经被“吹”了很久了,但是到现在为止也没有一个成熟完整的解决方案,虽然我之前几个自己写的项目都是使用MVVM(databinding为基础),但是那都是小打小闹。据我所知的“大厂”中没有使用MVVM来当做真正的解决方案的。所以如果大家对这种MVVM有兴趣的话,可以去看看我之前写的几篇博客和项目。另外说一句,我会自己从零开始封装一个MVP的框架,也算对自己一个挑战吧。
- 2.okhttp+retrofit:这两个框架想必大家都很熟悉了,我就不多说了。只是我会在项目的过程中对这两个框架进行深度的定制以实现一些有意思的东西,所以这一方面还是有点看头的。
- 3.fresco:这个也是广为人知的框架了,可以说这是最强大和性能最好的图片框架了吧。不是我“吹”这个框架,虽然他的缺点有一些比如:侵入性强、框架比较重。但是一个像抖音这样的音视频app,使用fresco是非常适合的,其他图片框架像glide、picasso等等,都有功能不全的问题。此外因为我完整的读过fresco的源码,所以我也可以对fresco进行比较深度的定制。对fresco源码感兴趣的同学也可以去翻翻我之前的博客。
- 4.插件化+组件化+热修复:这几个东西算是类似的吧,我还是一个个说
- 1.插件化:几个优点分别是,多成员负责不同的模块的时候加快编译速度、各个模块解耦、减小发版的包大小按需加载。使用的框架我倾向于自己写一个,但是不知道有没有时间,最后可能会在tinker和360RePlugin中选择一个吧。
- 2.组件化:其实和插件化类似,主要用于解耦模块,用到的技术是路由组件和gradle分模块依赖技术,倾向于自己写一个。
- 3.热修复:主要用于应对线上bug,应该会在andfix和Robust里面选一个,毕竟我们的项目对这个要求不高
- 5.google新MVVM组件:这是google最近发布的组件套装ViewModel+Room+Lifecycles+LiveData,虽然我们用的是MVP框架,但是google推荐的组件使用起来还是用好处的。
- 1.首先Room就可以抛弃了,他是数据库的组件,我们有更好的选择
- 2.ViewModel:第一个功能可以使ViewModel以及ViewModel 中的数据在屏幕旋转或配置更改引起的Activity重建时存活下来,重建后数据可继续使用,第二个功能可以帮助开发者轻易实现Fragment与Fragment之间,Activity与Fragment之间的通讯以及共享数据,所以还是很有必要使用的,可以集成在我们的MVP框架中。
- 3.Lifecycles:这个就不用说了,生命周期组件是Android官方架构组件中的核心组件,它可以使各种实例作为观察者与Activity和Fragment等具有生命周期特性的组件绑定在一起,LiveData和ViewModel,都是基于此组件,简而言之就是,你将需要绑定生命周期的实例注册给该组件,该组件就会在你指定的某个生命周期方法执行时通知这个实例。
- 4.LiveData:这个组件其实做的和Rxjava的事情类似,第一个功能是观察者模式,在Value发生变化时通知之前注册的所有观察者,第二功能是基于生命周期组件与Activity和Fragment等具有生命周期特性的组件绑定在一起,在生命周期发生改变时停止或恢复之前的事件。了解Rxjava的同学都知道这些功能在其拓展包中都是有的,所以这个组件我们可以不使用。
- 6.Rxjava:不用说Rxjava的生态已经很成熟了,他有RxCache,RxLifecycle,RxAndroid,RxPermission,Retrofit-Adapter等大量并且强大的衍生库,在写项目的过程中我也会对使用到的Rxjava的功能进行分析。
- 7.AOP技术:这个技术用处很多,比如日志记录、自动埋点等等,目前候选的框架有:AspectJ、APT和ASM这些到时候看实现日志和埋点框架的时候再选吧。
- 8.JNA:可能有些同学不了解这个框架,其实这就是一个代替jni的对java开发者更加友好的调用native方法的框架,因为我前面说了我们这个项目主要目的是实现抖音中的各种特效,所以必不可少的会用到jni,因此我用了JNA这个更加方便的库。
- 9.opencv:目前我也没有开始了解我司到底是使用了哪种技术来实现视频中的各种特效,所以暂定是opencv,以后随着我深入核心代码,可能框架会改变。再次声明,本项目中的代码并不会有任何我司的核心代码,所以大家最好别将项目代码用于商业项目
- 10.深度学习框架:我之前也使用过tensorflow lite,但是这个框架太简陋了,所以现在的有一个新选择是腾讯的ncnn,这个问题将会在到了该使用深度学习的时候再选择。另外如果对tensorflow lite有兴趣的同学可以去看看我之前写的图片处理APP的和一个使用demo。
- 11.数据库:初步预想是使用GreenDao,使用起来方便一些,而且我们对于数据库使用程度并不强,我司就是使用这个框架,所以还是可靠的。
- 12.WebView:最近hybird app非常流行,所以项目里先把这个技术占一个坑吧,到时候可能会实现一个简陋的与js互相调用的WebView容器吧,到时候再看。
- 13.待补充,不知道还有什么技术或者框架是一个成熟的App应该使用的,所以之后想到会陆续补充,如果大家有什么建议,特别、十分、非常、超级的欢迎在评论区指出来,十分感谢!
三、尾巴
在最后想和大家聊聊我的想法与未来android工程师的发展道路。
1.如何当好一个大厂的螺丝钉
- 1.都说面试造核弹,入职拧螺丝,我虽然是一个才刚入职的应届生,但是感触也颇多。入职之前希望做点有意思的事情,能多么多么牛逼。但是其实大多数人进入了大厂都是有可替代性的,真正不可替代的只是顶部的小部分人,所以最后大多数人每天的工作就是维护业务,接需求,修bug。我就是大多数人中的一份子,我怕我就这样适应了这种工作,然后一天天的重复相同的事情失去了激情,最终为了钱在码代码退变成为一名光荣的“代码搬运工”。
- 2.所以如何当好一个大厂的螺丝钉?辞职是不可能辞职的,这几年都不会辞职的,大厂福利和薪资又这么好,只能去利用公司的资源学习更多的东西,才能勉强维持激情。所以我才会决定开这个项目的坑,不断学习公司里的技术做一些自己没做过的事情,保持初心提升自己。
2.android工程师的发展道路
- 1.“我要转前端”、“我要转后台”、“android开发没人要了”......想必这些话在各种android技术群里时长会出现,这样也加深了不少android工程师的焦虑感。但是我想说的只有一句话:牛逼的人做啥都牛逼,只有人的问题没有方向的问题。
- 2.为什么android工程师没人要了?首先我们得明确一点,在可预期的时间范围内(五年内)android这个平台是不会死的。在我看来只有更加新型的交互操作系统(ar、vr、mr?)会革了android的命,但是最近是看不到希望的。明确了上面一点,我们就可以聊聊为啥android没人要了。
- 1.第一个原因可能是经济问题导致公司倒闭了,那么App就少了,这个无解。
- 2.第二个原因应该就是hybird App、类react native框架、小程序、flutter等等跨平台解决方案的崛起。
- 1.首先hybird App可以不用管,因为“慢”是一个永恒的问题。其次“小程序”在我看来也不是一个大问题,但凡一个大一点的互联网公司都会有原生App,因为你不可能把自己的小命完全交给腾讯。
- 2.所以现在在和原生android抢地盘的就是类react native框架与flutter。其实我们可以这么看,这两种其实都是通过js写业务逻辑然后将绘制逻辑通过c++交给native控件,所以只要你学的深并不用怕这两个东西抢了你的饭碗。
- 3.android工程师的发展道路在哪?我目前想到的一个词就是“深挖”,具体体现在:深入三方框架源码、深入framework、深入c++层、深入音视频处理以及深度学习。我想大家从我前面的项目概述中就能知道为啥了。成为一个只有很少人能替代的人,才是你我的核心竞争力。
3.计划
说了这么多,我来定一个计划吧,也算是接下来整个项目的计划表,这样也好推动我进行项目的更新。其实上面概述中提到的技术我只熟悉1/3,希望我能坚持下去在接下来的1年里能完成这个对于我来说宏大的项目。(暂定两周一个推进节点,写一篇博客,项目大更新一版)
- 1.完成项目基础结构的搭建,熟悉概述中的各个不熟悉的技术
- 2.完成自建MVP框架和组件化路由框架的编写
- 3.将google新MVVM组件集成进自建MVP组件中,完成日志框架编写
- 4.完成埋点框架编写,写一个python服务器进行埋点数据以及其他需要上传服务器的数据展示(上)
- 5.深入学习ncnn框架,写一个python服务器进行埋点数据以及其他需要上传服务器的数据展示(下)
- 6-10.开始画界面,着重学习公司核心代码,着重继续学习深度学习
- 11-20.界面画完开始实现特效每个节点实现两个特效,同时学习公司核心代码和继续学习深度学习
- 20之后.离一年还有6个节点,算是进行收尾工作以及为中间突发事件留下的机动时间。
- 另外.前1-5中会适当学习公司核心代码以及深度学习