Android面试指南:第三章

作者: LogosLi | 来源:发表于2017-08-12 15:17 被阅读163次
面试指南

前言

终于写到Android高级知识的面试题部分了,前面的知识点只是工具的使用和知识点的回顾,还有就是API调用中出现的各种问题和注意事项,我们可以找点工具就解决的问题,或者是百度一下就能够马上解决的问题,可是在实际开发中我们需要对一系列机制和框架有所了解之后才能谈使用何种框架去写我们的代码,采用何种设计模式去定义我们的Application,还有一部分需要自己去形成思路的知识,需要我们花点时间去理解一下的,此处我会讲一下大致的四路,大致上大家可以自己去调试和尝试一下,毕竟技术本身就是不断实践和累积的一个过程,前面的知识点如果能掌握全,说明你至少还是可以写代码的,可是却还是缺乏一点自我的主动性或者思考能力理解整个架构,如果你能跟上,我们继续前行的,在之后的项目中我们也可以采用容器的思想和各种机制的特性来解决一系列的问题,另外必须说明一下,我一个人码字也是一件特别辛苦的事情,不过也算是我对Android开发的一个总结,我不是一个功利的人,我想要的一切我自己回去争取,何况我不止能够写技术性的文章,我还能写文艺性的文章,本身也只是我个人对于写作的一种坚持,此致,敬所有熬心写作的作者。

Android性能优化

其实我们的应用交给我们的测试或者我们自己在手机上玩一下我们就能了解这个应用的在不同手机上的性能如何,可是作为一个Android工程师,我们必须了解一下造成性能不好原因何在,不然让我们如何对付测试和老板的,最后还要背锅的。
一、UI卡顿的性能优化
原理:通常我们说一部典型的帧率在24fps,我们的人眼是无法觉察到的,原因是里面有过渡帧,可是一个纯粹的动画,我们说需要维系在60fps人眼才会无法觉察,换一个单位就是16ms/帧人才不会觉察到卡顿的现象。
卡顿的原因
1.最为常见的就是在UI线程中做了耗时操作,不过通常会报出ANR的异常。
2.还有就是我们的布局文件太过复杂了,无法在16ms内渲染完毕,当然你的手机性能本身也是一个瓶颈。
3.执行的动画太多,CPU或者GPU负载太重了,这个的确是一个极为重要的原因,而且假设你们公司的App要适配低端机子就必须减少损耗性能的动画。
4.代码逻辑出问题了,资源文件的冗余现象严重
5.频繁出发绘制以及gc机制以及IO读写导致的线程阻塞现象。
6.过度绘制的问题,导致我们手机的CPU超负荷进行的操作。
解决方法
1.使用HierarchyViewer分析我们的视图树结构,AS中通过tools打开我们的DDMS,里面就有我们的视图树功能,里面会显示出所有的树结构,我们可以分析一下多余的树结构和嵌套,减少不必要的树结构或者优化一系列的树结构,我们在布局中也已经提到过,而且树结构中会显示出三个彩色的点,分别代表着测量,布局和绘制的快慢,从快到慢依次为:绿色,黄色以及红色,假设为红色不一定就代表太慢,这和树结构本身的复杂度有关系。
2.我们的Android手机全部会有开发者选项,我们使用这个开发者选项开查询到一个App的布局情况,当然树结构还是可以通过上述的功能去查询到,以前也有人是这样去仿造别人的App进行布局处理的,毕竟大公司出的App质量可能有保障一点,当然还可以查询GPU渲染的情况,此处我们最为主要的是要查询过渡绘制的情况,假设我3层或者3层以上可能就需要引起我们的注意了,通常会显示为了淡红色或者是红色了,我们需要尽量减少不必要的绘制区域,比方说对canvas的绘制区域进行设定,另外还有就是对不需要绘制的View进行隐藏处理,也可以显示出绘制的FPS作为参考,对FPS较低的渲染进行重点的优化。
3.另外在我们的AS有一个分析工具,可以分析我们整个Project,也可以只分析我们的整个Module,当然还可以是分析一段代码资源,从中可以提示好多的Lint让我们去修改。
4.在AS中的Monitor中已经集成了对Memory,CPU,GPU以及Network的监视,在我们的内存监视中我们可以进行手动的GC回收,当然我们也可以在Monitor中监视一下内存被大量占用的时期,此时最有可能爆发我们的OOM,以及gc去回收占用大量的时间,我们说在onDraw方法中尽量不要创建对象,测量,布局以及绘制本身就是一个Android中View的渲染过程,我们不能在此处的任何一个环节进行一个损耗性能的操作,或者是创建大量的对象,当然我们的AS也继承了TraceView获取方法执行时间的方法,就在CPU上有一个生成方法执行时间的按钮,我们可以观察到每一个方法的执行时间,以此判断是否在特定的方法中产生了卡顿的现象,当然我们在DDMS中还有一个可以监视到CPU具体的执行时间的Trace:sysTrace,我们点击一下就能生成一个html文件,直接就可以打开,里面会显示出柱状图,我们可以显示绘制的时间,如果渲染不能再16ms完成的,我们说通常就是存在所谓的卡顿现象,可是比较遗憾的是我们不能直接查询引起卡顿的具体原因,通常来讲我们说这种工作不会由我们的测试去指出,只能通过我们自身去发现问题的所在,还有就是说我们的必须检测App的ANR现象,我们说友盟可能无法检测到这种现象的出现,在我们的项目中可引入bugly(腾讯的SDK)来检测我们的ANR现象,以及采集到ANR之后产生的log日志,我们可以根据这个log具体去分析产生ANR的原因,当然也有可能是用户手机自己造成的,在直播App中这种ANR发生的概率需要被控制在一定的数值范畴之内,
5.布局优化我们在布局中已经提到过,尽量使用我们的include标签,merge标签以及延迟加载的Viewstub标签,weight尽量使用0dp去运算,列表在滑翔状态尽量不要进行列表的更新,然后就是图片的优化,此处我们重点谈一下图片的优化,首先我们说在我们的Android处理的是位图,位图有:
ALPHA_8:每个像素占用1byte内存
ARGB_4444:每个像素占用2byte内存
ARGB_8888:每个像素占用4byte内存 (默认)
RGB_565:每个像素占用2byte内存
我们在从磁盘读取的时,需要给特定一下图片的质量,另外就是使用Option对图片进行压缩的处理,包括图片尺寸以及其它方面的处理。
还有需要注意的是使用完我们的图片之后要对我们的图片进行回收,要把引用置为null,最后主动调用一下我们的gc来释放我们的内存。
当然如果我们想要避免我们的程序由于OOM崩溃了,最好的方法就是直接捕获这个异常,返回一张不占资源的默认图片,这个我认为是必须要做的事情,否则你的用户体验将会太差。
假设图片实在太占内存还可以使用我们的LRUCache进行管理,里面维护了一个LinkedhashMap,可以内存超过我们的缓存值时,删除最近最少用的一个对象,里面维系了一个算法来进行对象的删除,当然在Disk里面也有这个管理的体系:DiskLruCache,大家了解一下就可以了,当然我们也可以使用图片加载的框架,之前我可能也已经提到过,好多的在ListView和GridView进行滑翔时是不会去加载图片资源的,另外就是我们上面可能提到过ListView图片错位的出现原因,就是由于复用造成的,显示了上一张加载的图,我们要对其进行隐藏处理,在我们当前的图片还未加载或者加载完毕时。
假设出现一张不能压缩的超大图片我该如何去处理,其实Android早就API10时就引入了一个类BitmapRegionDecoder,这个类显示的图片不会引发OOM,关键是进行了局部的加载,比方说地图还有超大的画,我们可以配合我们的手势控制器来进行查阅这个图片,进行移动这个图片,可是对于这种图片是有特定的格式需求的,我认为可能大部分人用不到,算是增长一下我们的见识,图片的性能优化我们就谈到此处。
二、内存优化
内存泄露
又是一个重点,内存泄露通常以前是会使用我们的MAT进行查询的,现在我们的AS也已经可以查询到,也是使用一下GC回收,生成一个dump文件,里面直接可以分析一下内存泄露的,直接可以帮助我们进行一下内存泄露的定位,后来我们普遍会使用一个square足迹的leakcanary来查询,这个App能够提早帮助我们发现内存泄露的现象,最为关键的是还能够帮助我们去定位泄露的来源,这个简直不要太棒,讲了这么多可能大家已经厌烦了,我们还是想要理解一下内存泄露,也就是说当一个对象我们已经不需要引用时,我们通常想让这个对象被gc所回收,可是这个对象还在GROOT下被直接或者间接地引用着,导致这个对象无法被GC所回收,这就是我们所说的内存泄露,内存泄露肯定会造成不必要的内存垃圾,会占用我们的内存资源,所以我们要防止内存泄露的发生,我们在发现和定位问题之后要去处理问题,以及我们在Android编程可以注意一下,就能避免我们的内存泄露出现:
1.我们说Context使用不当会引发我们的内存泄露,此处我们尽量使用Application进行引用,这个生命周期可以维系到App退出,当然有的地方是这个引用所无法替代的。
2.在我们任何一个类中,当然通常就是指我们的Activity,当这个类被销毁时,线程不能还有未执行完毕的任务,我们必须手动关闭这个线程。
3.流对象,Cusor对象,WebVvew之类的全部需要手动去关闭,还有对象的注册和反注册必须成对出现,比方说我们的广播接收者的动态注册。
4.不能在执行频率特别高的方法中创建对象,等于是反复创建对象了,我们前面也已经说了不能再onDraw()方法中不断地创建对象。
5.最好使用静态内部类,不要使用我们的普通内部类,否则外类对象持有内部类对象可能无法被销毁。
6.代码设计中的错误造成的内存泄露,主要就是依靠检测发现和整改了,这一切全部是经验。
内存溢出(OOM)
我们说Android会为我们的每一个应用分配一个dvm实例,当然是从zygote里面fork出来的,当然有一块就是我们的共享内存区域,当然我们前面已经说dvm是基于寄存器的,寄存器上的是一系列的栈内存操作,这和我们的jvm在内存之中进行的栈操作是类似的,当然也会给我们的dvm分配一块堆内存,以前是最大值为16MB,现在的手机内存空间大了之后,可能会有32MB,也有可能为64MB,关键是手机厂商会对我们的ROM包进行修改,之后我们在阅读我们的启动源码时也会谈到堆内存分配的源码,当然对于这个内存还有一个调配的机制,我们此处就不展开去讲了,另外就是我们的内存是可以动态申请的,以前在项目曾经用到过,是一个系统管理的项目,所谓的OOM绝大多数情况下是由于我们的堆内存溢出所造成的,下面我们讲一下实际开发中如何避免我们的OOM:
1.尽量不要加载大图到我们的内存之中,在图片优化中我们已经谈过对图片的优化,此处不再赘述,通常我会使用google官方提供的Glide去加载我们的图片,也会咋ListView之类的滑动控件在滑翔时不会去加载图片,方便。
2.避免内存泄露,我们说内存溢出可能是由于内存泄露所造成的。
3.尽可能使用缓存设计,不用每一个去读取资源
4.使用线程池,重复使用我们的资源文件。
5.尽可能不要使用依赖注入,无卵用。
6.使用异常捕获我们的OOM异常,不要让我们的应用强制退出。
三、其它优化建议
1.onTrimMemory()和onLowMermory:这个方法的回调时告诉我们的应用,系统内存不足了,要开始kill进程了,回调时我们可以释放内存,避免被我们的系统kill掉。
2.还是代码方面的问题,比方说不要用枚举,不要用增强for,使用SparseArray替代我们的HashMap,当值为int类型,还有就是bean类里面不要写set和get方法,直接使用我们的public修饰我们的成员变量,关于这方面的代码需求我们可与参考一下华为代码编写规范,我曾经读过里面对于代码的质量进行了严格的把控。
3.关于耗电方面网络请求和游戏渲染肯定是最为耗电的,还有高强度的CPU运算,通常在我们的移动端用不到,除非是一系列的设计软件,可以会设计到高强度的运算,我们不要开启太多的线程处理任务就是能省电,当然这是不可能的,只能是尽量,还有就是不要启动移动端的硬件设备,比方说计时的AlarmManager(通常是连接我们的RTC计时芯片),还有就是GPS定位和WiFi,也可以使用powerManager监视我们的电量使用情况,做一定的优化,我们的优化就讲到此处。

Android的测量,布局以及绘制流程(自定义控件的基础之一)

在我们入门去将Android的绘制流程之前,当然我此处不会继续去上源码,当然也有可能源码会被改掉了,我们所说的源码也就是Frame层面的Java源码,而不是涉及到到类库的源码,我们的大部分同学的电脑可能是windows系统的电脑,我们说这个系统最大的特征就是窗口模式,当然这个思想也被我们的Android所导入,我们的Window是一个抽象,里面封装了窗口的全部调用设置,包括里面的交互接口以及界面的绘制,全部可以是交给我们的Window去实现的,当然我们的Android在其之上还维系了一个Activity用来管理我们的视图以及处理相关的交互事件,当然最终是通过我们的ViewRoot将Activity和我们Window联结到了一起,这个ViewRoot不是我们的根节点View,我们的跟节点View通常是我们的DecorView,另外我们说Window中必然会跟随出现一个Surface(想像成我们的屏幕)和视图树(每一个Window里面只能存在一个视图树,也就是我们设定的xml布局文件。谈到Surface我想大家可能会想到我们的SurfaceView,其实这个控件就是封装了一个Window对象,我们的Surface就是一个双缓冲机制,这个我想大家不会陌生,也就是一个backCanvas和frontCanvas,后台的画布会把渲染好的画布post到前台的画布,通常也就是我们所说的屏幕上,当然我们的Surface需要锁定我们的画布,绘制完毕之后才能解锁,SurfaceView其实也是维系了一个Window对象的,在绘制完毕之后,只是把前台的Window设置为了透明色而已,Canvas相当于是一个绘制接口,在了解大体上的这个框架之后我们记着来讲我们的之后测量,定位以及绘制的过程。
测量:整个测量过程是从我们的根View开始的,此处需要明白一个事情,就假设我们申请重新测量也是会从我们的根测量开始,我们的系统先会调用我们的measure方法,之后在我们的这个方法中调用onMeasure当然我们说会将测量的宽高值传进去,我们说onMeasure是可以重写的,可是这时我们的尺寸还未被测量出来,在onMeasure方法中我们必须调用我们的setMeasuresDimens才能完成整个的测量过程,我们说每一个ViewGroup需要对子孩子进行测量(就是其中的一个方法),也会调用子孩子的measure方法,当然也会把自己的测量值传入进行去,之后我们可以通过onMeasure()进行测量值的重定义,可是父元素的定义可能会对子孩子的测量产生影响,下面我们就把这种影响附上一个图,不是我总结的,我只是帮助大家梳理一下:

父子视图关系

上面会进行递归测量的,我们已经了解了这个原理,对于我们理解我们的layout过程就更加简单了,无非也就是这样的递归调用,直接使用子孩子进行递归调用,通常假设我们的继承一个ViewGroup需要重写我们的onLayout方法,这是一个抽象的方法,使用我们的这个方法对子孩子进行布局就可以了,我们的View通常不需要关心这个布局,这个布局是相对于父布局进行的布局,View'本身不能成为一个Layout,而只是widget,还有就是getWidth和getHeight是在layout方法被执行之后才能够获取的。
关于draw的整个绘制过程,我想说可能会多两个方法,分别为dispatchDraw和onDrawScrollbars方法,也是从draw方法开始,在这个方法中调用onDraw()以及其它的方法,dispatchDraw方法会调用子孩子的draw方法,最后会onDrawScrollbars,这个是绘制我们的水平或者是垂直的滚动条,其实我们不需要太过关注,或许你从未用过。
补充:我们测量,布局以及绘制从树根开始是会判断一下是否需要进行才会引发的,也就是说存在一个状态值,而不是每一个invalidate就会从上之下的重绘,也不是说每一个requestLayout就会重新测量和布局,一开始视图树肯定是要经历完整的过程,之后句不需要了,对上面的知识有了一定的了解之后,我个人认为还需要对于我们的Canvas绘制API有一定的熟悉度,之后配合我们对于Andoid触摸事件的了解我们才能按照一定思路去写出我们的自定义控件,或者说是流畅地写出我们的自定义控件,有人说自定义控件是Android开发的一个进阶标识,相信我们的开发人员在实际工作中也写过不少的自定义控件或者是实现特定的动画效果,此处我们说动画比较重视的事件轴,也就是一帧或者说一幅图出现的时间,将所有的图片连在一起就形成了最为原始的动画:帧动画,其它动画从本质上来讲也是如此,只是呈现方法可能会有所不同,下面我们还是继续深入一下自定义控件的另一个基础Android的Touch事件机制以及手势控制器。

Android中的Touch机制

我们说我们还是需要找传递这个事件的源头,dispatchTouchEvent方法,这个方面中会调用我们的onTouch方法,当然这个方法当我们的控件不是enable状态下是无法被调用的,还有一种情况是我们的onTouch方法直接返回了false,或者我们说当mTouchListener为null值时我们说会调用我们的onTouchEvent方法,dispatchTouchEvent方法的返回值就是我们onTouchEvent()方法的返回值。
我们就事件分发的关键点说一下:
1.我们说在事件分发中涉及到了两个类,分别为我们的View和ViewGroup,所有的类中执行的全部是分发的方法,在分发的方法中调用我们的其它方法,在我们的View还有一个onTouch的方法会被调用这个,被调用的前提是这个View必须是可以enable的,而且我们的mTouchListener对象不能为null,另外我们说假设dispatchTouchEvent返回true就是说分发事件已经被处理或者说被消费,通常这个返回值和我们的onTouchEvent()的返回值一致,而不会继续分发下去。
2.我们会去找到一个View去处理我们的分发事件,假设这个View要处理这个事件,等同是返回true说自己要消费这个事件,我们会保存这个对象,下次直接传到这个对象的onTouchEvent方法里面,当然也可能会被我们的父布局给拦截,我们可以申请父布局不要拦截我们之后的MOVE和UP事件。
3.假设我们的子View不去处理这个事件,则会返回到我们的父布局中使用到父布局的onTouchEvent方法,假设还是返回false,我们说就会最终交给我们的Activity去处理,最终这个事件无法处理就被作废了。
4.另外有一个事情,可能是一个常识,就是就算我们在onTouchEvent里面返回了false,也就是说事件会被回传,可是我们说在返回之前的代码还是会被执行的,这个请大家切记。
5.其实所谓的Touch事件实质就是我们进行的一种手势操作,所以Android给我们封装了一个手势处理器。
注意:可能我在此处的分析极为的简单,其实整个所谓的Touch事件框架本身我认为就是特别的简单,只是我们封装的框架中需要自行执行判断,比方说你要使用一个无Scroll的ViewPager,其实重写一下分发的方法直接返回一下true,就不会处理任何的细节了,可是问题是所有的事件在父容器中全部被接收了,而不做任何的事情,你里面包含的子View可能根本就无法响应Touch事件,我们让我们只要不拦截事件就可以了,之后让我们的父控件的onTouchEvent进行空实现。

关于线程间的通信

这时我们可能会接触到一个最为经典的问题,就是我们能不能在我们的子线程中Toast一个信息,其实是可以的,我们的Toast不一定非要在我们的UI线程中进行,其实是需要一个Looper对象绑定我们当前的Thread,new一个Handler接收信息和发送信息,最后开启阻塞式的接收信息的状态,我们说这个过程就能让我们的Toast成功,也就是说我们就能在主线程给我们的子线程主动发送消息,或者说进行主动的通信,其实这也是涉及到我们线程间通信的一个处理,相信大家对于轻量级别的框架,也是square出品的otto不会太过陌生,这个框架也是用于我们的线程间通信,还有一个后面我们会使用的EventBus(当初也是读过源码的),现在最新的3.0版本引入了apt的注解处理器,不用书写指定的方法名称以及通过方法指定线程开启模式,以及是否接收黏性消息,当然不要忘了注册我们的订阅者,这也是一个挺好用的框架,里面也是进行了一个单例化的设计,黏性信息在订阅者还未注册时会保留在特定的内存中,假设注册了一个订阅者,接收我们所谓的黏性信息,就可以接收到这个黏性信息,可是这个信息就这样被消费,这也就是我们所说的延迟消费,可是要注意到的这个黏性消息会一直在,一旦有人注册接收黏性消息就会发送过去,有时当我们不需要时我们可以remove掉我们的这个黏性消息,这也是大部分人会用处错误来的一个原因,比方说我们的Activity可能会出现重复注册的情况,就可能会出现重复接收信息的现象,所以要记着在适当的时机将其clear掉,和我们的黏性广播是一样的,当然此处有人可能还会说使用我们最新的RXjava或者是RxAndroid进行响应式的编程,所实话现在如果在你的项目中大量地使用线程间通信,个人还是推进使用EventBus,这个框架已经经过优化和各种问题的验证,至少我们能在网上查询到各种的问题的解决方案,当然现在也有所谓的RxBus,对于Rxjava个人认为最为主要的还是线程间的调度,我们说被观察者在接收到观察者,进行观察者的方法回调时,能够进行耗时性的操作,之后在我们的观察者回调中,将数据传给我们的观察者进行UI线程的更新操作,而这一切的操作只要在一个链式编程结构中实现,我个人认为极为方便,当然还可以结合我们最新的网络框架进行使用,比方说OkHttp和我们的Retrofit,个人建议不要使用github上的针对这两个网络框架的封装,先不说封装的水平如何,封装必定会影响一系列原本的框架提供给我们的细节设置,转而编程一种封装者的处理模式,这对于我们来讲框架一旦出现了问题,或者是网络访问的细节需要改变时就会比较尴尬,而且是对Http网络访问的封装,其实我们需要了解一下这个协议的网络访问过程,这对我们处理各种网络问题还是有好处的,至少我们需要明白这个问题是出在我们的客户端,还是我们的后端,相信不少人被后端虐过,我们必须武装起来,开个玩笑,其实当前可以调试的工具和网络框架一定是特别多的,基本我瞧了一眼也能马上应用,可是工具的本质也是一种对底层的封装,我们需要熟悉特定层面的知识,才能应付工具本身出现的各种问题。

关于网络框架

早前Andoid向我们的是两个框架,一个是重量级别的框架HttpClient,以及一个轻量级别的框架HttpUrlConnection,之后的所谓网络框架全部是对这两个框架的一个封装,包括google自行推出的AsyncTask,里面是一个线程池,当然也可以加入一点访问网络的方式,当然这个框架目前不建议使用,我们又响应式编程更好的框架RxJava,另外我们说这个框架还有一个超级强大的功能我们称之为线程切换,简直就是神器,又实现了数据间的线程通信,还有一个封装了HttpClient的HttpUtils我相信不少人还在使用,我上一个项目中的一个组员还在用这个网络框架,当然我还是不说这个框架不好的,只是有点过时了,有时感觉持续地做项目不一定能提升你的技术水平,你只会使用自己所熟悉的框架,而且一直使用,还有一个经常被我们使用,而且已经被我们验证的框架,我们称之为Volley框架,这个框架的出现主要是为了我们频繁地请求网络而设计的,包括队列的设计,缓存的设计,可是也线路出这个框架不足的地方,对于较大数据的下载和上传实在是不给力的,可是我相信已经有不少人已经在使用这个框架,这个框架会暴露出一部分的问题,不过网上大家已经有解决的方法,比方说你沿用Cache的方案会导致整个界面无法被及时更新,而是使用了原先的缓存界面和数据,我相信早期的Android开发玩家应该已经封装过,我们的Google是为解决频繁访问网络的一个优化,而引入我们的OkHttp是发现这个网络框架不仅仅解决频繁访问网络的优化问题,而且使用自己新出的SDPY对http访问进行了优化,而且优先判断是否可以使用HTTP/2的协议,加速我们的访问速度,当然还有针对同一个地址共用一个socket的优化,这个框架确实比我们的Volley要好用不少,所以google直接将其纳入官方推荐的网络框架了,只是回调在子线程,需要使用runOnUIThread()方法返回到我们的主线程之中进行UI的更新工作,不过我们说Jake Wharton已经去google工作,据说说负责kotlin方面的工作,当然我们还可以使用对OkHttp采用了封装的Retrofit框架,此处不展开去解释各个框架的使用方法,主要是我们大家要对我们的Http协议本身要有所理解才能够用到这种网络封装框架的功能,包括cookies,网络缓存,路由,session,token之类的含义,其实全部是封装数据的一种类而已,只是我们需要存储数据,之后获取数据之后,根据数据对我们的交互界面进行设定。
补充:关于数字签名,我觉着凡是打包过Apk的人就不会陌生,现在我们大部分会使用我们的Fir以及蒲公英,毕竟这种平台有免费的可以使用,谁也不想多花钱,另外就是多渠道打包之后,就是在使用gradle打包时做上不同的标记,好让我们区分不同市场的App,这样我们就能监视我们的App在不同市场上的下载量情况,可以有选择性地进行下架处理,当然网上也出了好多的框架,当然Android版本的变化可能也会带来兼容性的问题,基本上最新的框架已经解决掉了,小伙伴也不用太操心,数字签名是唯一的,不像我们的CA认证是用来通信认证的,而是用来自我认证,可以是这是唯一的标示,说明这两个应用是同一个应用,当我们升级时就会进行覆盖安装,我们经常会被问到是否可以进行静默安装,实际上手机root之后是可以的,就是linux底层的命令,当然有人说不用root也能够进行所谓的静默安装,或许是进入到残疾人模式实现代码的点击事件,帮助我们进行确认安装,显现出来就是静默安装的方式,当然之后最后一章我会花点时间和大家聊一下我们在Android中的各种技术手段,此处我们先就我们的Android的高级知识了解一下,我个人觉着掌握了差不多的高级知识,之后你可能还要去了解设计模式之类的,必须先了解性能,时间和空间的换算,这一切才是根本,不是硬性地采用所谓的设计模式。

Android中的动画

通常分为:补间动画,帧动画,属性动画,值动画,矩阵动画以及gif(也是中动画模式)
补间动画:不是真正的移动我们的View,只是一个动画效果而已,真正的View还在原地,而且可以被点击,动画本身不能被点击,主要就是移动,放大缩小,旋转以及透明度变化的效果,还有一个动画集合。
2.帧动画:这就是涉及到动画和视频原理层面了,就是一帧一帧的图片,可是在视频中我们说会经过H264的编码处理(硬解码可以使用openGL,软解码使用的是CPU自身的渲染引擎),不然视频超级大的,还有PIB帧的保存方式,就是一帧帧的图片每一张图片有自身的播放时间,可是这个动画我跟你讲,如同还未经过编码的视频,太损耗性能了,而且人们如果对这个动画感觉无卡顿感,起码要维系在16ms/帧的基础,建议假设客户机的性能不好的情况最好不要用这种动画。
3.所谓属性动画,就是一个View自身的属性有一个变化的过程,或者是一个时间,我们需要指定一下起始属性值以及结束的属性值,之后设定一下变化时间。
4.所谓的值动画又是对属性动画的一个提升了,在前端中有这样的写法也是如此,就是监视动画执行的进度来设定我们的View属性,从动画进度的属性设置我们View的变化动画,通过监听我们可以动画执行的各个状态,通过状态值,我们就可以进行对应的操作了,所谓的Value是我们自己设定的一个变化值区间,我们可以获取这个值区间用来计算我们每一个阶段需要设定的属性值,也就是说会根据值本身的进度来进行我们属性的设置,从达到我们的动画效果(使用Evaluator来运算,Android里面已经提供给我们)。
5.矩阵动画,我说任何的图片在我我们的显示器上不过是像素矩阵,这个像素矩阵可以按照特定的规律进行变化,就会形成动画,这就是我们的Matrix的作用,也能实现动画效果,而且更加偏向底层的实现,性能方面可能会好点。
6.另外就是加载我们的gif图片,gif图片的质量普遍不高,而且比较占资源,建议使用lottie框架直接导入json文件进行播放,这也是一个最好的方法,最为直接的播放的方式,直接让美工给我们做就好了,转换为json数据,我们直接使用框架进行加载。
补充:复杂一点的动画,Android已经提供了我们插值器进行使用,大家有空去了解一下插值器的使用,我们Fragment和Activity我们全部可以定义进入和出去的过场动画,前者我们说存在一个问题,就是不能开启事务,否则可能会出现crash,Andoid在高版本中已经解决了这个问题,另外后者可以通过代码定义,也可以通过我们的方法定义,之后在新特性中Android也提供一系列定义过场动画的方法,我们在之后的新特性面试题中和大家讲解一下。
补充:NineOldAndroids:是这个写链式代码,而且写动画是极好的,里面封装了我们的属性动画还有我们的值动画。

其它常用的框架和平台

地图比方说高德地图,推送可以使用个推,极光推送,尽管我们说BAT有大礼包可是我们说不太专业,友盟统计被阿里收购了,也还是可以的,可是据说无法检测我们的ANR,所以通常对于bugly追踪有特殊要求的公司可以使用一下腾讯的Buly,广告收入推荐大家使用有米,当然这可能是个人开发者会用的,大一点的可能想要广告推送系统为自己所用的,毕竟是盈利点,可是有米帮我找好了广告主,对个人开发者和小公司而言是我们的福音,mob短信验证,这个我就不说了,还有第三方登录和授权,不过你要去打通各个平台的开发者账号,ping++是集成了支付。
补充:当然还有打包工具,java项目管理神器jenkins的使用,大家在实际开发中可能会用到,集中到我们的Android中我相信也不是难事,其它的问题大部分集中在业务代码的书写上,不同行业,有着不同的业务流程,一定要对公司的产品设计和业务流程有着一定的了解,有的好行业,当你进入到这个行业继续开发工作时会升职加薪,另外就我个人而言,我认为这样也能提升选择另一个行业进行转型,或者是找到另一条赚钱的路径,期待我在第四章的最后总结以及就一部分其它技术的说明,其实个人认为在IT领域除了环境的部署,业务结构的代码,API的熟练度以及其具体的系统机制,不会涉及太过艰深的算法体系,统计,深度学习或者说机器学习不过也就是对统计公式的一种运用罢了,我们也不过是一个调参者,毕竟创造算法还是只能是数学家,这个算法是否具有商业价值,这就是难说了,说实话要是有钱,或者是可干点其它的事情,我绝对不会继续在IT领域干了,全是水分,现在是天下项目一大抄,不过钱的确比其它行业多了不少,现在还可以挤一挤。

相关文章

  • Android开发

    《Android 开发工程师面试指南》 《Android 开发工程师面试指南 LearningNotes 》,作者...

  • 无标题文章

    转载自《Android 开发工程师面试指南》 《Android 开发工程师面试指南 LearningNotes 》...

  • 面试要点记录

    Android面试知识库Android 开发工程师面试指南Material Design 学习资料面试题Andro...

  • 2018春招实习面试

    看到了一个Android面试指南的网站,强力推荐:Android校招面试指南 以下可能并不是确切的面试问题,但都涉...

  • Android 面试指南

    向大家推荐《Android 面试指南》 https://xiaozhuanlan.com/android-inte...

  • Android面试相关

    link 杭州找 Android 工作的点点滴滴 《Android 开发工程师面试指南》 亲爱的面试官,这个我可没...

  • 《Android 开发工程师面试指南》-转

    《Android 开发工程师面试指南 LearningNotes 》,作者是知乎Android开发工程师陶程,由梁...

  • Android 开发工程师面试指南

    《Android 开发工程师面试指南 LearningNotes 》,作者是知乎Android开发工程师陶程,由梁...

  • Android攻城狮面试指南

    《Android 开发工程师面试指南 LearningNotes 》,作者是知乎Android开发工程师陶程,由梁...

  • Android面试指南:第三章

    前言 终于写到Android高级知识的面试题部分了,前面的知识点只是工具的使用和知识点的回顾,还有就是API调用中...

网友评论

  • 12e36795b1ea:老公,棒棒的
  • 2cedb0101a59:正在准备面试,能遇到作者这么用心的人真是太幸运了。
    LogosLi:@木子逸_guula 作者正在公司写布局,不然第四章就有了
  • e43165de9c4a:受益颇多!

本文标题:Android面试指南:第三章

本文链接:https://www.haomeiwen.com/subject/hqkjrxtx.html