写点什么

10 道阿里 Android 岗必问题摆这儿了,你爱刷不刷!,透彻解析

用户头像
Android架构
关注
发布于: 1 小时前
  • START_NOT_STICKY: 如果返回 START_NOT_STICKY,表示当 Service 运行的进程被 Android 系统强制杀掉之后,不会重新创建该 Service

  • START_REDELIVER_INTENT: 如果返回 START_REDELIVER_INTENT,其返回情况与 START_STICKY 类似,但不同的是系统会保留最后一次传入 onStartCommand 方法中的 Intent 再次保留下来并再次传入到重新创建后的 Service 的 onStartCommand 方法中


3.2 提高 Service 的优先级 在 AndroidManifest.xml 文件中对于 intent-filter 可以通过 android:priority ="1000"这个属性设置最高优先级,1000 是最高值,如果数字越小则优先级越低,同时适用于广播;


3.3 在 onDestroy 方法里重启 Service 当 service 走到 onDestroy()时,发送一个自定义广播,当收到广播时,重新启动 service;


3.4 提升 Service 进程的优先级 进程优先级由高到低:前台进程 一 可视进程 一 服务进程 一 后台进程 一空进程 可以使用 startForeground 将 service 放到前台状态,这样低内存时,被杀死的概率会低一些;


3.5 系统广播监听 Service 状态;


3.6 将 APK 安装到/system/app,变身为系统级应用;


注意:以上机制都不能百分百保证 Service 不被杀死,除非做到系统白名单,与系统同生共死。

[](

)4. 描述一下 Android 数据持久存储方式


参考回答: Android 平台实现数据持久存储的常见几种方式:


  • SharedPreferences 存储:一种轻型的数据存储方式,本质是基于 XML 文件存储的 key-value 键值对数据,通常用来存储一些简单的配置信息(如应用程序的各种配置信息);

  • SQLite 数据库存储:一种轻量级嵌入式数据库引擎,它的运算速度非常快,占用资源很少,常用来存储大量复杂的关系数据;

  • ContentProvider:四大组件之一,用于数据的存储和共享,不仅可以让不同应用程序之间进行数据共享,还可以选择只对哪一部分数据进行共享,可保证程序中的隐私数据不会有泄漏风险;

  • File 文件存储:写入和读取文件的方法和 Java 中实现 I/O 的程序一样;网络存储:主要在远程的服务器中存储相关数据,用户操作的相关数据可以同步到服务器上;

[](

)5. Android 中 IPC 方式、各种方式优缺点,为什么选择 Binder?


参考回答:



**与 Linux 上传统的 IPC 机制,比如 System V,Soc


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ket 相比,Binder 好在哪呢?**


  • 传输效率高、可操作性强


传输效率主要影响因素是内存拷贝的次数,拷贝次数越少,传输速率越高。从 Android 进程架构角度分析:对于消息队列、Socket 和管道来说,数据先从发送方的缓存区拷贝到内核开辟的缓存区中,再从内核缓存区拷贝到


接收方的缓存区,一共两次拷贝,如图:



而对于 Binder 来说,数据从发送方的缓存区拷贝到内核的缓存区,而接收方的缓存区与内核的缓存区是映射到同


一块物理地址的,节省了一次数据拷贝的过程,如图:



由于共享内存操作复杂,综合来看,Binder 的传输效率是最好的。


  • 实现 C/S 架构方便: Linux 的众 IPC 方式除了 Socket 以外都不是基于 C/S 架构,而 Socket 主要用于网络间的通信且传输效率较低。Binder 基于 C/S 架构 ,Server 端与 Client 端相对独立,稳定性较好。

  • 安全性高: 传统 Linux IPC 的接收方无法获得对方进程可靠的 UID/PID,从而无法鉴别对方身份;而 Binder 机制为每个进程分配了 UID/PID 且在 Binder 通信时会根据 UID/PID 进行有效性检测。

[](

)6. Bundle 传递对象为什么需要序列化?Serialzable 和 Parcelable 的区别?


参考回答:


  • 因为 bundle 传递数据时只支持基本数据类型,所以在传递对象时需要序列化转换成可存储或可传输的本质状态(字节流)。序列化后的对象可以在网络、IPC(比如启动另一个进程的 Activity、Service 和 Reciver)之间进行传输,也可以存储到本地。

  • 序列化实现的两种方式:实现 Serializable/Parcelable 接口。不同点如图:


[](

)7. 如何解决 View 的事件冲突 ? 举个开发中遇到的例子?


参考回答:


  • 常见开发中事件冲突的有 ScrollView 与 RecyclerView 的滑动冲突、RecyclerView 内嵌同时滑动同一方向。

  • 滑动冲突的处理规则:


1.对于由于外部滑动和内部滑动方向不一致导致的滑动冲突,可以根据滑动的方向判断谁来拦截事件。


2.对于由于外部滑动方向和内部滑动方向一致导致的滑动冲突,可以根据业务需求,规定何时让外部 View 拦截事件,何时由内部 View 拦截事件。


3.对于上面两种情况的嵌套,相对复杂,可同样根据需求在业务上找到突破点。


  • 滑动冲突的实现方法:


1.外部拦截法:指点击事件都先经过父容器的拦截处理,如果父容器需要此事件就拦截,否则就不拦截。具体方法:需要重写父容器的 onInterceptTouchEvent 方法,在内部做出相应的拦截。


2.内部拦截法:指父容器不拦截任何事件,而将所有的事件都传递给子容器,如果子容器需要此事件就直接消耗,否则就交由父容器进行处理。具体方法:需要配合 requestDisallowInterceptTouchEvent 方法。

[](

)8. Looper 死循环为什么不会导致应用卡死?


参考回答:


  • 主线程的主要方法就是消息循环,一旦退出消息循环,那么你的应用也就退出了,Looer.loop()方法可能会引起主线程的阻塞,但只要它的消息循环没有被阻塞,能一直处理事件就不会产生 ANR 异常。

  • 造成 ANR 的不是主线程阻塞,而是主线程的 Looper 消息处理过程发生了任务阻塞,无法响应手势操作,不能及时刷新 UI。

  • 阻塞与程序无响应没有必然关系,虽然主线程在没有消息可处理的时候是阻塞的,但是只要保证有消息的时候能够立刻处理,程序是不会无响应的

[](

)9. Bitmap 如何处理大图,如一张 30M 的大图,如何预防 OOM?


参考回答:避免 OOM 的问题就需要对大图片的加载进行管理,主要通过缩放来减小图片的内存占用。


  • BitmapFactory 提供的加载图片的四类方法(decodeFile、decodeResource、decodeStream、decodeByteArray)都支持 BitmapFactory.Options 参数,通过 inSampleSize 参数就可以很方便地对一个图片进行采样缩放

  • 比如一张 10241024 的高清图片来说。那么它占有的内存为 102410244,即 4MB,如果 inSampleSize 为 2,那么采样后的图片占用内存只有 512512*4,即 1MB(注意:根据最新的官方文档指出,inSampleSize 的取值应该总是为 2 的指数,即 1、2、4、8 等等,如果外界输入不足为 2 的指数,系统也会默认选择最接近 2 的指数代替,比如 2)

  • 综合考虑。通过采样率即可有效加载图片,流程如下:


1.将 BitmapFactory.Options 的 inJustDecodeBounds 参数设为 true 并加载图片;


2.从 BitmapFactory.Options 中取出图片的原始宽高信息,它们对应 outWidth 和 outHeight 参数;


3.根据采样率的规则并结合目标 View 的所需大小计算出采样率 inSampleSize;


4.将 BitmapFactory.Options 的 inJustDecodeBounds 参数设为 false,重新加载图片;



用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
10道阿里Android岗必问题摆这儿了,你爱刷不刷!,透彻解析