- java中 classloader 的作用和工作原理?
- Android中自定义View有什么用处?
- 自定义view的三个回调方法以及它们的作用?
- 四大组件是什么?
- 常用的布局文件是什么(至少写四个)?
- okhttp是什么?内部大概是怎么实现?
- 什么是EventBus,基于什么模式,实现原理是什么?
一个可以简化Activity,Fragment、Thread、Service等之间交流的开源库。
基于发布订阅模式。在App的开发过程中,需要管理组件之间的信息交流。
design-patterns-event-bus - Activity的7个周期回调方法是什么
- 举出三种常用的线程池,并说明对应线程池的作用和特点。
- AsyncTask主要用来干什么的?内部是怎么实现的?
- 列举AsyncTask的主要的一些回调方法。
- Garbage Collector 是如何工作的?
Memory heap在Android Art运行时分成不同空间- Zygote Space
- Non Movng Space
- Image Space
- Main Alloc Space
- Large Obj Space
将堆分成不同空间便于以后GC的管理。
当你新创建一个对象,通过各种特性考量,将其分配到不同的空间,比如 new ArrayList()
ART将会在 Main Alloc Space中分配。
在GC工作的时候,所有当前执行的操作都会被挂起即常说的 “stop the world” ,待gc完成之后被挂起的操作才会继续被执行。在ART扩展了并发GC,使得因为GC暂停的时间更少(相对于Dalvik而言)。
而对于 Dalvik分成3个不同空间(Space)
- Liner Alloc
- Zygote Space
- Alloc Space
对于GC怎么工作的,先看看在dalvik vm中是如何工作的?
Dalvik相对于其他java平台的虚拟机而言它没有Compacting(堆压缩),比如在hotspot中,GC的过程中可能对象的地址会发生改变,也就是说对象在虚拟机内存中的位置是随时变化流动的,相当于把散落在堆上的对象聚成一坨。而对于在Dalvik中对象的地址一旦被分配,直到它被回收都不会发生改变,于是使得虚拟机的实现上变得简单。
当为对象分配内存空间失败的时候,垃圾回收(garbage collection就会触发)
实际上的GC 是使用标记-清除算法(Mark-Sweep algorithm) ,这种算法跟踪程序中所有直接或间接访问的对象,被程序直接访问的对象,你比如被一些静态引用引用的对象,一些正在处理的局部变量引用的对象,这些对象组成一个 roots集合。标记就从这些对象开始。该算法分成两个阶段,其中 一个是标记阶段,标记所有可达的对象。然后垃圾回收器扫描整个堆,将未被标记的对象回收。
相比较Dalvik而言,Art在8.0中加入了堆压缩(compacting)
-
Activity与Fragment之间是什么关系?
-
描述一个Activity启动的过程,为什么通过Intent?
简单来说一个Activity
启动另一个Activity
是通过Intent来启动的,一个Activity将需要被启动的新Activity
的信息放到intent
中,然后交给ActivityManagerService
然后由它来创建新的Activity。ActivityManagerService
是负责新Activity
的创建,管理Actvity
的生命周期,以及Activity的Stack。
ActivityThread
在Android系统中,每一个进程都用一个ActivityThread实例表示,每一个进程都与ActivityThread相关联 -
如何改善App程序的性能,所需采取的措施?
在开发过程中注意一些问题会提高App的性能,提高App的流畅度。App性能出现问题,大部分情况下是垃圾回收器的频繁调用,最终导致。大量对象的频繁创建和销毁会导致垃圾回收器频繁调用,比如创建bitmap过一会在销毁,glide中的解决办法是利用一个Bitmap池。其次是内存泄漏,内存一点一点的被占用,每次垃圾回收器不能全部回收。常见的比较大的对象泄漏,比如Activity Leak。短时间内大量线程的创建,线程管理的不佳,导致线程没有被及时回收。一般需要利用线程池来管理线程。其次是页面的绘制,需要在16ms内完成,因此draw等方法不能做太多无效的绘制,因而增加绘制时间。
对于有大量数据操作的App常出现的问题:
- 比较长的启动时间。
- 不流畅的滑动
- 不能及时响应用户操作。
出现Activity Leak的几点地方:
- Activity或者Fragment 被静态引用.
m_staticActivity = staticFragment.getActivity()
- Listener Leak. 内部类会持有外部类的引用,一般Listener会是一个内部类形式的出现。
- Handler Leak. 一般Handler会是在Activity中创建,如果hanlder.postDelay(…),而这期间Activity关闭就会发生泄漏。
一般修复因内部类发生的Activity泄漏,使用的是WeakReference,你不是默认会存储外部类(这里是Activity)的引用吗,那我就明着
存储,将它变成一个WeakReference。
避免Activity内存泄漏:
- 尽量避免静态引用
- 使用EventBus
- 及时删除监听器
- 能用内部静态类,就用静态类。
不流畅的滚动
UI线程只做UI相关的工作,不做其他耗时操作。
其他的,比如:
- 图片的缓存、加载。
- 网络操作。考虑okHttp、volley等第三方库,那么okHttp vs volley。
- 大Json串的解析,解析会产生性能影响。将大Json变成相关的类,提供getter和setter方法。
使用Gson或者Jack来处理Json的解析。 - 数据库访问。
Concurrency API。
Service
Service原本是运行在主线程(UI Thread)的。
所以在使用Service在做后台任务的时候,可以考虑使用
- IntentService
内部实现 HandlerThread + Handler + Looper
所以它是,单线程工作,处理简单任务,不会跟踪工作进度。
没有方式去停止,自己执行完成就停止。 - AsyncTask
内部实现 线程池+Handler - Executors
- HandlerThread,Handlers和Looper