写点什么

Android 常见原理性面试题 (1),2021 年阿里 Android 面试题精选

用户头像
Android架构
关注
发布于: 5 小时前

2) Thread 普通线程,如果需要有自


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


己的消息队列,需要调用 Looper.prepare()创建 Looper 实例,调用 loop()去循环消息。


3) HandlerThread 是一个带有 Looper 的线程,在 HandleThread 的 run()方法中调用了 Looper.prepare()创建了 Looper 实例,并调用 Looper.loop()开启了 Loop 循环,循环从消息队列中获取消息并交由 Handler 处理。利用该线程的 Looper 创建 Handler 实例,此 Handler 的 handleMessage()方法是运行在子线程中的。即 Handler 利用哪个线程的 Looper 创建的实例,它就和相应的线程绑定到一起,处理该线程上的消息,它的 handleMessage()方法就是在那个线程中运行的,无参构造默认是主线程。


HandlerThread 提供了 quit()/quitSafely()方法退出 HandlerThread 的消息循环,它们分别调用 Looper 的 quit 和 quitSafely 方法,quit 会将消息队列中的所有消息移除,而 quitSafely 会将消息队列所有延迟消息移除,非延迟消息派发出去让 Handler 去处理。


HandlerThread 适合处理本地 IO 读写操作(读写数据库或文件),因为本地 IO 操作耗时不长,对于单线程+异步队列不会产生较大阻塞,而网络操作相对比较耗时,容易阻塞后面的请求,因此 HandlerThread 不适合加入网络操作。


  • 3.handler 发消息给子线程,looper 怎么启动?


  • 4.关于 Handler,在任何地方 new Handler 都是什么线程下?


  • 5.ThreadLocal 原理,实现及如何保证 Local 属性?


  • 6.请解释下在单线程模型中 Message、Handler、Message Queue、Looper 之间的关系


  • 7.请描述一下 View 事件传递分发机制


  • 8.Touch 事件传递流程


  • 9.事件分发中的 onTouch 和 onTouchEvent 有什么区别,又该如何使用?


  • 10.View 和 ViewGroup 分别有哪些事件分发相关的回调方法


  • 11.View 刷新机制


  • 12.View 绘制流程


  • 13.自定义控件原理


  • 14.自定义 View 如何提供获取 View 属性的接口?


  • 15.Android 代码中实现 WAP 方式联网


  • 16.AsyncTask 机制


  • 17.AsyncTask 原理及不足


  • 18.如何取消 AsyncTask?


  • 19.为什么不能在子线程更新 UI?


  • 20.ANR 产生的原因是什么?


  • 21.ANR 定位和修正


  • 22.oom 是什么?


(oom(Out Of Memory)内存溢出)


  • 23.什么情况导致 oom?


  • 24.有什么解决方法可以避免 OOM?


  • 25.Oom 是否可以 try catch?为什么?


(可以,当)

[](

)26.内存泄漏是什么?


内存泄露就是指该被 GC 垃圾回收的,但被一个生命周期比它长的对象仍然在引用它,导致无法回收,造成内存泄露,过多的内存泄露会导致 OOM。

[](

)27.什么情况导致内存泄漏?


  1. 非静态内部类、匿名内部类:非静态内部类、匿名内部类 都会持有外部类的一个引用,如果有一个静态变量引用了非静态内部类或者匿名内部类,导致非静态内部类或者匿名内部类的生命周期比外部类(Activity)长,就会导致外部类在该被回收的时候,无法被回收掉,引起内存泄露, 除非外部类被卸载。


解决办法:将非静态内部类、匿名内部类 改成静态内部类,或者直接抽离成一个外部类。 如果在静态内部类中,需要引用外部类对象,那么可以将这个引用封装在一个 WeakReference 中。


2)静态的 View:当一个 Activity 经常启动,但是对应的 View 读取非常耗时,我们可以通过静态 View 变量来保持对该 Activity 的 rootView 引用。这样就可以不用每次启动 Activity 都去读取并渲染 View 了。但 View attach 到我们的 Window 上,就会持有一个 Context(即 Activity)的引用。而我们的 View 有事一个静态变量,所以导致 Activity 不被回收。


解决办法: 在使用静态 View 时,需要确保在资源回收时,将静态 View detach 掉。


3)Handler:在 Activity 中定义 Handler 对象,那么 Handler 持有 Activty 的引用。而每个 Message 对象是持有 Handler 的引用的(Message 对象的 target 属性持有 Handler 引用),从而导致 Message 间接引用到了 Activity。如果在 Activty destroy 之后,消息队列中还有 Message 对象,Activty 是不会被回收的。


解决办法: 将 Handler 放入单独的类或者将 Handler 放入到静态内部类中(静态内部类不会持有外部类的引用)。如果想要在 handler 内部去调用所在的外部类 Activity,可以在 handler 内部使用弱引用的方式指向所在 Activity,在 onDestory 时,调用相应的方法移除回调和删除消息。


4)监听器(各种需要注册的 Listener,Watcher 等):当我们需要使用系统服务时,比如执行某些后台任务、为硬件访问提供接口等等系统服务。我们需要把自己注册到服务的监听器中。然而,这会让服务持有 activity 的引用,如果程序员忘记在 activity 销毁时取消注册,那就会导致 activity 泄漏了。


解决办法:在 onDestory 中移除注册


5)资源对象没关闭造成内存泄漏:当我们打开资源时,一般都会使用缓存。比如读写文件资源、打开数据库资源、使用 Bitmap 资源等等。当我们不再使用时,应该关闭它们,使得缓存内存区域及时回收。


解决办法:使用 try finally 结合,在 try 块中打开资源,在 finally 中关闭资源


6)属性动画:在使用 ValueAnimator 或者 ObjectAnimator 时,如果没有及时做 cancel 取消动画,就可能造成内存泄露。因为在 cancel 方法里,最后调用了 endAnimation(); ,在 endAnimation 里,有个 AnimationHandler 的单例,会持有属性动画对象的引用。


解决办法:在 onDestory 中调用动画的 cancel 方法


7)RxJava:在使用 RxJava 时,如果在发布了一个订阅后,由于没有及时取消,导致 Activity/Fragment 无法销毁,导致的内存泄露。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android常见原理性面试题(1),2021年阿里Android面试题精选